/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ddf;
import java.util.
ArrayList;
import java.util.
Collections;
import java.util.
Comparator;
import java.util.
Iterator;
import java.util.
List;
import org.apache.poi.util.
LittleEndian;
/**
* Common abstract class for {@link EscherOptRecord} and
* {@link EscherTertiaryOptRecord}
*/
public abstract class
AbstractEscherOptRecord extends
EscherRecord
{
private
List<
EscherProperty>
properties = new
ArrayList<
EscherProperty>();
/**
* Add a property to this record.
*
* @param prop the escher property to add
*/
public void
addEscherProperty(
EscherProperty prop )
{
properties.
add(
prop );
}
@
Override
public int
fillFields( byte[]
data, int
offset,
EscherRecordFactory recordFactory )
{
int
bytesRemaining =
readHeader(
data,
offset );
short
propertiesCount =
readInstance(
data,
offset );
int
pos =
offset + 8;
EscherPropertyFactory f = new
EscherPropertyFactory();
properties =
f.
createProperties(
data,
pos,
propertiesCount );
return
bytesRemaining + 8;
}
/**
* The list of properties stored by this record.
*
* @return the list of properties
*/
public
List<
EscherProperty>
getEscherProperties()
{
return
properties;
}
/**
* The list of properties stored by this record.
*
* @param index the ordinal index of the property
* @return the escher property
*/
public
EscherProperty getEscherProperty( int
index )
{
return
properties.
get(
index );
}
private int
getPropertiesSize()
{
int
totalSize = 0;
for (
EscherProperty property :
properties )
{
totalSize +=
property.
getPropertySize();
}
return
totalSize;
}
@
Override
public int
getRecordSize()
{
return 8 +
getPropertiesSize();
}
public <T extends
EscherProperty> T
lookup( int
propId )
{
for (
EscherProperty prop :
properties )
{
if (
prop.
getPropertyNumber() ==
propId )
{
@
SuppressWarnings( "unchecked" )
final T
result = (T)
prop;
return
result;
}
}
return null;
}
@
Override
public int
serialize( int
offset, byte[]
data,
EscherSerializationListener listener )
{
listener.
beforeRecordSerialize(
offset,
getRecordId(), this );
LittleEndian.
putShort(
data,
offset,
getOptions() );
LittleEndian.
putShort(
data,
offset + 2,
getRecordId() );
LittleEndian.
putInt(
data,
offset + 4,
getPropertiesSize() );
int
pos =
offset + 8;
for (
EscherProperty property :
properties )
{
pos +=
property.
serializeSimplePart(
data,
pos );
}
for (
EscherProperty property :
properties )
{
pos +=
property.
serializeComplexPart(
data,
pos );
}
listener.
afterRecordSerialize(
pos,
getRecordId(),
pos -
offset, this );
return
pos -
offset;
}
/**
* Records should be sorted by property number before being stored.
*/
public void
sortProperties()
{
Collections.
sort(
properties, new
Comparator<
EscherProperty>()
{
@
Override
public int
compare(
EscherProperty p1,
EscherProperty p2 )
{
short
s1 =
p1.
getPropertyNumber();
short
s2 =
p2.
getPropertyNumber();
return
s1 <
s2 ? -1 :
s1 ==
s2 ? 0 : 1;
}
} );
}
/**
* Set an escher property. If a property with given propId already
exists it is replaced.
*
* @param value the property to set.
*/
public void
setEscherProperty(
EscherProperty value){
for (
Iterator<
EscherProperty>
iterator =
properties.
iterator();
iterator.
hasNext(); ) {
EscherProperty prop =
iterator.
next();
if (
prop.
getId() ==
value.
getId()){
iterator.
remove();
}
}
properties.
add(
value );
sortProperties();
}
public void
removeEscherProperty(int
num){
for (
Iterator<
EscherProperty>
iterator =
getEscherProperties().
iterator();
iterator.
hasNext(); ) {
EscherProperty prop =
iterator.
next();
if (
prop.
getPropertyNumber() ==
num){
iterator.
remove();
}
}
}
@
Override
protected
Object[][]
getAttributeMap() {
List<
Object>
attrList = new
ArrayList<
Object>(
properties.
size()*2+2);
attrList.
add("properties");
attrList.
add(
properties.
size());
for (
EscherProperty property :
properties ) {
attrList.
add(
property.
getName());
attrList.
add(
property);
}
return new
Object[][]{
{ "isContainer",
isContainerRecord() },
{ "numchildren",
getChildRecords().
size() },
attrList.
toArray()
};
}
}