PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/components/forks/poi/src/loci/poi/ddf/DefaultEscherRecordFactory.java

http://github.com/openmicroscopy/bioformats
Java | 177 lines | 96 code | 12 blank | 69 comment | 20 complexity | c686784da3da38fecea2e5b988b86ece MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-2-Clause, MPL-2.0-no-copyleft-exception
  1. /*
  2. * #%L
  3. * Fork of Apache Jakarta POI.
  4. * %%
  5. * Copyright (C) 2008 - 2013 Open Microscopy Environment:
  6. * - Board of Regents of the University of Wisconsin-Madison
  7. * - Glencoe Software, Inc.
  8. * - University of Dundee
  9. * %%
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. * #L%
  22. */
  23. /* ====================================================================
  24. Licensed to the Apache Software Foundation (ASF) under one or more
  25. contributor license agreements. See the NOTICE file distributed with
  26. this work for additional information regarding copyright ownership.
  27. The ASF licenses this file to You under the Apache License, Version 2.0
  28. (the "License"); you may not use this file except in compliance with
  29. the License. You may obtain a copy of the License at
  30. http://www.apache.org/licenses/LICENSE-2.0
  31. Unless required by applicable law or agreed to in writing, software
  32. distributed under the License is distributed on an "AS IS" BASIS,
  33. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  34. See the License for the specific language governing permissions and
  35. limitations under the License.
  36. ==================================================================== */
  37. package loci.poi.ddf;
  38. import loci.poi.hssf.record.RecordFormatException;
  39. import java.lang.reflect.Constructor;
  40. import java.util.HashMap;
  41. import java.util.Map;
  42. /**
  43. * Generates escher records when provided the byte array containing those records.
  44. *
  45. * @author Glen Stampoultzis
  46. * @author Nick Burch (nick at torchbox . com)
  47. *
  48. * @see EscherRecordFactory
  49. */
  50. public class DefaultEscherRecordFactory
  51. implements EscherRecordFactory
  52. {
  53. private static Class[] escherRecordClasses = {
  54. EscherBSERecord.class, EscherOptRecord.class, EscherClientAnchorRecord.class, EscherDgRecord.class,
  55. EscherSpgrRecord.class, EscherSpRecord.class, EscherClientDataRecord.class, EscherDggRecord.class,
  56. EscherSplitMenuColorsRecord.class, EscherChildAnchorRecord.class, EscherTextboxRecord.class
  57. };
  58. private static Map recordsMap = recordsToMap( escherRecordClasses );
  59. /**
  60. * Creates an instance of the escher record factory
  61. */
  62. public DefaultEscherRecordFactory()
  63. {
  64. }
  65. /**
  66. * Generates an escher record including the any children contained under that record.
  67. * An exception is thrown if the record could not be generated.
  68. *
  69. * @param data The byte array containing the records
  70. * @param offset The starting offset into the byte array
  71. * @return The generated escher record
  72. */
  73. public EscherRecord createRecord( byte[] data, int offset )
  74. {
  75. EscherRecord.EscherRecordHeader header = EscherRecord.EscherRecordHeader.readHeader( data, offset );
  76. // Options of 0x000F means container record
  77. // However, EscherTextboxRecord are containers of records for the
  78. // host application, not of other Escher records, so treat them
  79. // differently
  80. if ( ( header.getOptions() & (short) 0x000F ) == (short) 0x000F
  81. && header.getRecordId() != EscherTextboxRecord.RECORD_ID ) {
  82. EscherContainerRecord r = new EscherContainerRecord();
  83. r.setRecordId( header.getRecordId() );
  84. r.setOptions( header.getOptions() );
  85. return r;
  86. }
  87. else if ( header.getRecordId() >= EscherBlipRecord.RECORD_ID_START && header.getRecordId() <= EscherBlipRecord.RECORD_ID_END )
  88. {
  89. EscherBlipRecord r;
  90. if (header.getRecordId() == EscherBitmapBlip.RECORD_ID_DIB ||
  91. header.getRecordId() == EscherBitmapBlip.RECORD_ID_JPEG ||
  92. header.getRecordId() == EscherBitmapBlip.RECORD_ID_PNG)
  93. {
  94. r = new EscherBitmapBlip();
  95. }
  96. else if (header.getRecordId() == EscherMetafileBlip.RECORD_ID_EMF ||
  97. header.getRecordId() == EscherMetafileBlip.RECORD_ID_WMF ||
  98. header.getRecordId() == EscherMetafileBlip.RECORD_ID_PICT)
  99. {
  100. r = new EscherMetafileBlip();
  101. }
  102. else
  103. {
  104. r = new EscherBlipRecord();
  105. }
  106. r.setRecordId( header.getRecordId() );
  107. r.setOptions( header.getOptions() );
  108. return r;
  109. }
  110. else
  111. {
  112. Constructor recordConstructor = (Constructor) recordsMap.get( new Short( header.getRecordId() ) );
  113. EscherRecord escherRecord = null;
  114. if ( recordConstructor != null )
  115. {
  116. try
  117. {
  118. escherRecord = (EscherRecord) recordConstructor.newInstance( new Object[]{} );
  119. escherRecord.setRecordId( header.getRecordId() );
  120. escherRecord.setOptions( header.getOptions() );
  121. }
  122. catch ( Exception e )
  123. {
  124. escherRecord = null;
  125. }
  126. }
  127. return escherRecord == null ? new UnknownEscherRecord() : escherRecord;
  128. }
  129. }
  130. /**
  131. * Converts from a list of classes into a map that contains the record id as the key and
  132. * the Constructor in the value part of the map. It does this by using reflection to look up
  133. * the RECORD_ID field then using reflection again to find a reference to the constructor.
  134. *
  135. * @param records The records to convert
  136. * @return The map containing the id/constructor pairs.
  137. */
  138. private static Map recordsToMap( Class[] records )
  139. {
  140. Map result = new HashMap();
  141. Constructor constructor;
  142. for ( int i = 0; i < records.length; i++ )
  143. {
  144. Class record = null;
  145. short sid = 0;
  146. record = records[i];
  147. try
  148. {
  149. sid = record.getField( "RECORD_ID" ).getShort( null );
  150. constructor = record.getConstructor( new Class[]
  151. {
  152. } );
  153. }
  154. catch ( Exception illegalArgumentException )
  155. {
  156. throw new RecordFormatException(
  157. "Unable to determine record types" );
  158. }
  159. result.put( new Short( sid ), constructor );
  160. }
  161. return result;
  162. }
  163. }