001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * StyleSheetCollection.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.style;
030:
031: import java.io.Serializable;
032: import java.util.HashMap;
033:
034: import org.jfree.report.util.InstanceID;
035:
036: /**
037: * The stylesheet collection manages all global stylesheets. It does not contain the
038: * element stylesheets.
039: * <p/>
040: * The stylesheet collection does not accept foreign stylesheets.
041: *
042: * @author Thomas Morgner
043: */
044: public class StyleSheetCollection implements Cloneable, Serializable {
045: protected static class ManagedStyleSheetCarrier implements
046: StyleSheetCarrier {
047: private InstanceID styleSheetID;
048: private ManagedStyleSheet styleSheet;
049: private ManagedStyleSheet self;
050:
051: public ManagedStyleSheetCarrier(final ManagedStyleSheet parent,
052: final ManagedStyleSheet self) {
053: this .styleSheetID = parent.getId();
054: this .styleSheet = parent;
055: this .self = self;
056: self.addListener(styleSheet);
057: }
058:
059: public ElementStyleSheet getStyleSheet() {
060: if (styleSheet != null) {
061: return styleSheet;
062: }
063: // just after the cloning ...
064: final StyleSheetCollection col = self
065: .getStyleSheetCollection();
066: styleSheet = (ManagedStyleSheet) col
067: .getStyleSheetByID(styleSheetID);
068: if (styleSheet == null) {
069: // should not happen in a sane environment ..
070: throw new IllegalStateException(
071: "Stylesheet was not valid after restore operation.");
072: }
073: return styleSheet;
074: }
075:
076: protected void updateParentReference(
077: final ManagedStyleSheet self) {
078: this .self = self;
079: }
080:
081: public void invalidate() {
082: self.removeListener(getStyleSheet());
083: }
084:
085: public boolean isSame(final ElementStyleSheet style) {
086: return style.getId().equals(styleSheetID);
087: }
088:
089: public Object clone() throws CloneNotSupportedException {
090: final ManagedStyleSheetCarrier o = (ManagedStyleSheetCarrier) super
091: .clone();
092: o.styleSheet = null;
093: return o;
094: }
095: }
096:
097: protected static class ManagedStyleSheet extends ElementStyleSheet {
098: private StyleSheetCollection styleSheetCollection;
099:
100: /**
101: * @param name
102: * @param collection the stylesheet collection that created this stylesheet, or null,
103: * if it is a foreign or private stylesheet.
104: */
105: public ManagedStyleSheet(final String name,
106: final StyleSheetCollection collection) {
107: super (name);
108: if (collection == null) {
109: throw new NullPointerException();
110: }
111: this .styleSheetCollection = collection;
112: }
113:
114: /**
115: * Adds a parent style-sheet. This method adds the parent to the beginning of the
116: * list, and guarantees, that this parent is queried first.
117: *
118: * @param parent the parent (<code>null</code> not permitted).
119: */
120: public void addParent(final ManagedStyleSheet parent) {
121: super .addParent(0, parent);
122: }
123:
124: /**
125: * Adds a parent style-sheet. Parents on a lower position are queried before any
126: * parent with an higher position in the list.
127: *
128: * @param position the position where to insert the parent style sheet
129: * @param parent the parent (<code>null</code> not permitted).
130: * @throws IndexOutOfBoundsException if the position is invalid (pos < 0 or pos
131: * >= numberOfParents)
132: */
133: public void addParent(final int position,
134: final ManagedStyleSheet parent) {
135: super .addParent(position, parent);
136: }
137:
138: /**
139: * Creates and returns a copy of this object. After the cloning, the new StyleSheet is
140: * no longer registered with its parents.
141: *
142: * @return a clone of this instance.
143: *
144: * @see Cloneable
145: */
146: public Object clone() throws CloneNotSupportedException {
147: final ManagedStyleSheet ms = (ManagedStyleSheet) super
148: .clone();
149: ms.styleSheetCollection = null;
150:
151: final StyleSheetCarrier[] sheets = ms.getParentReferences();
152: for (int i = 0; i < sheets.length; i++) {
153: final ManagedStyleSheetCarrier msc = (ManagedStyleSheetCarrier) sheets[i];
154: msc.updateParentReference(ms);
155: }
156: return ms;
157: }
158:
159: protected StyleSheetCarrier createCarrier(
160: final ElementStyleSheet styleSheet) {
161: if (styleSheet instanceof ManagedStyleSheet == false) {
162: throw new IllegalArgumentException(
163: "Only stylesheets that are managed by this stylesheet collection can be added");
164: }
165: final ManagedStyleSheet ms = (ManagedStyleSheet) styleSheet;
166: // yes, only this object, no clone, not logical the same, we mean PHYSICAL IDENTITY
167: if (ms.getStyleSheetCollection() != getStyleSheetCollection()) {
168: throw new IllegalArgumentException(
169: "Only stylesheets that are managed by this stylesheet collection can be added");
170: }
171: return new ManagedStyleSheetCarrier(ms, this );
172: }
173:
174: public ManagedStyleSheet createManagedCopy(
175: final StyleSheetCollection collection)
176: throws CloneNotSupportedException {
177: final ManagedStyleSheet es = (ManagedStyleSheet) getCopy();
178: es.setStyleSheetCollection(collection);
179: return es;
180: }
181:
182: public StyleSheetCollection getStyleSheetCollection() {
183: return styleSheetCollection;
184: }
185:
186: protected void setStyleSheetCollection(
187: final StyleSheetCollection styleSheetCollection) {
188: this .styleSheetCollection = styleSheetCollection;
189: }
190: }
191:
192: /**
193: * The stylesheet storage.
194: */
195: private HashMap styleSheets;
196: private HashMap styleSheetsByID;
197:
198: /**
199: * DefaultConstructor.
200: */
201: public StyleSheetCollection() {
202: styleSheets = new HashMap();
203: styleSheetsByID = new HashMap();
204: }
205:
206: /**
207: * @throws NullPointerException if the given stylesheet is null.
208: */
209: public ElementStyleSheet createStyleSheet(final String name) {
210: if (styleSheets.containsKey(name)) {
211: return (ElementStyleSheet) styleSheets.get(name);
212: }
213: final ElementStyleSheet value = new ManagedStyleSheet(name,
214: this );
215: styleSheets.put(name, value);
216: styleSheetsByID.put(value.getId(), value);
217: return value;
218: }
219:
220: public ElementStyleSheet getStyleSheet(final String name) {
221: return (ElementStyleSheet) styleSheets.get(name);
222: }
223:
224: public ElementStyleSheet getStyleSheetByID(final InstanceID name) {
225: return (ElementStyleSheet) styleSheetsByID.get(name);
226: }
227:
228: public Object clone() throws CloneNotSupportedException {
229: final StyleSheetCollection sc = (StyleSheetCollection) super
230: .clone();
231: sc.styleSheets = (HashMap) styleSheets.clone();
232: sc.styleSheetsByID = (HashMap) styleSheetsByID.clone();
233:
234: final ManagedStyleSheet[] styles = (ManagedStyleSheet[]) styleSheets
235: .values().toArray(
236: new ManagedStyleSheet[styleSheets.size()]);
237: final ManagedStyleSheet[] styleClones = (ManagedStyleSheet[]) styles
238: .clone();
239: // create the clones ...
240: for (int i = 0; i < styles.length; i++) {
241: final ManagedStyleSheet clone = styles[i]
242: .createManagedCopy(sc);
243: sc.styleSheets.put(clone.getName(), clone);
244: sc.styleSheetsByID.put(clone.getId(), clone);
245: styleClones[i] = clone;
246: }
247: return sc;
248: }
249: }
|