/*******************************************************************************
* Copyright (c) 2009, Adobe Systems Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* · Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* · Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* · Neither the name of Adobe Systems Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
package com.adobe.dp.office.rtf;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
public class RTFStyle {
String name;
RTFStyle parent;
private Hashtable storage;
private boolean clone;
private boolean locked;
public RTFStyle cloneStyle() {
RTFStyle s = new RTFStyle();
s.parent = parent;
s.storage = storage;
s.name = name;
s.clone = storage != null;
return s;
}
public Object get(String prop) {
if (storage == null)
return null;
return storage.get(prop);
}
void put(String prop, Object val) {
if (locked)
throw new IllegalStateException("locked");
if (storage == null)
storage = new Hashtable();
else if (clone) {
clone = false;
name = null;
storage = (Hashtable) storage.clone();
}
storage.put(prop, val);
}
void remove(String prop) {
if (locked)
throw new IllegalStateException("locked");
if (storage == null || storage.get(prop) == null)
return;
if (clone) {
clone = false;
name = null;
storage = (Hashtable) storage.clone();
}
storage.remove(prop);
}
public boolean isLocked() {
return locked;
}
public void lock() {
locked = true;
}
public boolean isEmpty() {
return storage == null || storage.isEmpty();
}
public Iterator properties() {
if (parent != null)
throw new IllegalStateException("needs to be collapsed to iterate");
return storage.keySet().iterator();
}
public static RTFStyle collapse(RTFStyle[] styles, Set propSet) {
RTFStyle rs = new RTFStyle();
for (int i = 0; i < styles.length; i++) {
for (RTFStyle s = styles[i]; s != null; s = s.parent) {
if (s.storage == null)
continue;
Iterator keys = s.storage.keySet().iterator();
while (keys.hasNext()) {
String k = (String) keys.next();
if (!propSet.contains(k))
continue;
if (rs.get(k) == null) {
Object v = s.storage.get(k);
rs.put(k, v);
}
}
}
}
return rs;
}
public RTFStyle collapse(Set propSet) {
RTFStyle[] s = { this };
return collapse(s, propSet);
}
public int hashCode() {
return (isEmpty() ? 0 : storage.hashCode()) + (parent == null ? 0 : parent.hashCode());
}
public boolean equals(Object other) {
if (other == null)
return false;
if (other.getClass() == getClass()) {
RTFStyle prop = (RTFStyle) other;
if (parent == null) {
if (prop.parent != null)
return false;
} else if (!parent.equals(prop.parent))
return false;
if (isEmpty())
return prop.isEmpty();
else
return storage.equals(prop.storage);
}
return false;
}
}