001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.ddf;
019:
020: import org.apache.poi.util.HexDump;
021: import org.apache.poi.util.LittleEndian;
022:
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.io.PrintWriter;
027:
028: /**
029: * Escher container records store other escher records as children.
030: * The container records themselves never store any information beyond
031: * the standard header used by all escher records. This one record is
032: * used to represent many different types of records.
033: *
034: * @author Glen Stampoultzis
035: */
036: public class EscherContainerRecord extends EscherRecord {
037: public static final short DGG_CONTAINER = (short) 0xF000;
038: public static final short BSTORE_CONTAINER = (short) 0xF001;
039: public static final short DG_CONTAINER = (short) 0xF002;
040: public static final short SPGR_CONTAINER = (short) 0xF003;
041: public static final short SP_CONTAINER = (short) 0xF004;
042: public static final short SOLVER_CONTAINER = (short) 0xF005;
043:
044: private List childRecords = new ArrayList();
045:
046: public int fillFields(byte[] data, int offset,
047: EscherRecordFactory recordFactory) {
048: int bytesRemaining = readHeader(data, offset);
049: int bytesWritten = 8;
050: offset += 8;
051: while (bytesRemaining > 0 && offset < data.length) {
052: EscherRecord child = recordFactory.createRecord(data,
053: offset);
054: int childBytesWritten = child.fillFields(data, offset,
055: recordFactory);
056: bytesWritten += childBytesWritten;
057: offset += childBytesWritten;
058: bytesRemaining -= childBytesWritten;
059: getChildRecords().add(child);
060: if (offset >= data.length && bytesRemaining > 0) {
061: System.out.println("WARNING: " + bytesRemaining
062: + " bytes remaining but no space left");
063: }
064: }
065: return bytesWritten;
066: }
067:
068: public int serialize(int offset, byte[] data,
069: EscherSerializationListener listener) {
070: listener.beforeRecordSerialize(offset, getRecordId(), this );
071:
072: LittleEndian.putShort(data, offset, getOptions());
073: LittleEndian.putShort(data, offset + 2, getRecordId());
074: int remainingBytes = 0;
075: for (Iterator iterator = getChildRecords().iterator(); iterator
076: .hasNext();) {
077: EscherRecord r = (EscherRecord) iterator.next();
078: remainingBytes += r.getRecordSize();
079: }
080: LittleEndian.putInt(data, offset + 4, remainingBytes);
081: int pos = offset + 8;
082: for (Iterator iterator = getChildRecords().iterator(); iterator
083: .hasNext();) {
084: EscherRecord r = (EscherRecord) iterator.next();
085: pos += r.serialize(pos, data, listener);
086: }
087:
088: listener.afterRecordSerialize(pos, getRecordId(), pos - offset,
089: this );
090: return pos - offset;
091: }
092:
093: public int getRecordSize() {
094: int childRecordsSize = 0;
095: for (Iterator iterator = getChildRecords().iterator(); iterator
096: .hasNext();) {
097: EscherRecord r = (EscherRecord) iterator.next();
098: childRecordsSize += r.getRecordSize();
099: }
100: return 8 + childRecordsSize;
101: }
102:
103: public List getChildRecords() {
104: return childRecords;
105: }
106:
107: public void setChildRecords(List childRecords) {
108: this .childRecords = childRecords;
109: }
110:
111: public String getRecordName() {
112: switch ((short) getRecordId()) {
113: case DGG_CONTAINER:
114: return "DggContainer";
115: case BSTORE_CONTAINER:
116: return "BStoreContainer";
117: case DG_CONTAINER:
118: return "DgContainer";
119: case SPGR_CONTAINER:
120: return "SpgrContainer";
121: case SP_CONTAINER:
122: return "SpContainer";
123: case SOLVER_CONTAINER:
124: return "SolverContainer";
125: default:
126: return "Container 0x" + HexDump.toHex(getRecordId());
127: }
128: }
129:
130: public void display(PrintWriter w, int indent) {
131: super .display(w, indent);
132: for (Iterator iterator = childRecords.iterator(); iterator
133: .hasNext();) {
134: EscherRecord escherRecord = (EscherRecord) iterator.next();
135: escherRecord.display(w, indent + 1);
136: }
137: }
138:
139: public void addChildRecord(EscherRecord record) {
140: this .childRecords.add(record);
141: }
142:
143: public String toString() {
144: String nl = System.getProperty("line.separator");
145:
146: StringBuffer children = new StringBuffer();
147: if (getChildRecords().size() > 0) {
148: children.append(" children: " + nl);
149: for (Iterator iterator = getChildRecords().iterator(); iterator
150: .hasNext();) {
151: EscherRecord record = (EscherRecord) iterator.next();
152: children.append(record.toString());
153: // children.append( nl );
154: }
155: }
156:
157: return getClass().getName() + " (" + getRecordName() + "):"
158: + nl + " isContainer: " + isContainerRecord() + nl
159: + " options: 0x" + HexDump.toHex(getOptions()) + nl
160: + " recordId: 0x" + HexDump.toHex(getRecordId()) + nl
161: + " numchildren: " + getChildRecords().size() + nl
162: + children.toString();
163:
164: }
165:
166: public EscherSpRecord getChildById(short recordId) {
167: for (Iterator iterator = childRecords.iterator(); iterator
168: .hasNext();) {
169: EscherRecord escherRecord = (EscherRecord) iterator.next();
170: if (escherRecord.getRecordId() == recordId)
171: return (EscherSpRecord) escherRecord;
172: }
173: return null;
174: }
175:
176: }
|