001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.struct;
025:
026: import jacareto.record.ReadAccessRecord;
027: import jacareto.struct.event.StructureChangeEvent;
028: import jacareto.struct.event.StructureChangeListener;
029: import jacareto.system.Environment;
030: import jacareto.system.EnvironmentMember;
031:
032: import java.util.Collection;
033: import java.util.Iterator;
034: import java.util.Vector;
035:
036: /**
037: * This abstract class represents a structure of structure elements or other objects.
038: *
039: * <p>
040: * Heirs of this abstract class must decide how object should be stored and how they should be read
041: * from a structure. Possible heirs could be <code>XMLStructure</code>.
042: * </p>
043: *
044: * <p>
045: * Objects which can be stored to a structure are structure element (see {@link StructureElement}).
046: * The record is setted by the method {@link #setRecord(jacareto.record.ReadAccessRecord)} and the
047: * structure is stored with the methode {@link #setRootElement(StructureElement)}.
048: * </p>
049: *
050: * <p>
051: * Subclasses should call the {@link ExternalStructure#fireStructureChange(StructureChangeEvent)}
052: * method whenever the content or the state of the structure changes. This method notifies all
053: * StructureChangeListeners added to this object of the structure change.
054: * </p>
055: *
056: * @author <a href="mailto:markus.bois@web.de">Markus Bois</a>
057: * @version 1.01
058: */
059: public abstract class ExternalStructure extends EnvironmentMember {
060: /** The vector of the structure change listeners to notify when this structure has changed. */
061: private Collection structureChangeListeners;
062:
063: /** Whether or not structure change listeners will be notified of structure changes. */
064: private boolean isNotificationEnabled;
065:
066: /**
067: * The constructor.
068: *
069: * @param env the environment
070: */
071: public ExternalStructure(Environment env) {
072: super (env);
073: structureChangeListeners = new Vector(10, 5);
074: isNotificationEnabled = true;
075: }
076:
077: /**
078: * Makes this structure get ready for storing. Should throw a {@link StructureException} if the
079: * structure is already open, for example.
080: *
081: * @throws StructureException if an error has occurred
082: */
083: public abstract void open() throws StructureException;
084:
085: /**
086: * Finishes adding. Should throw a {@link StructureException} if the structure is not open, for
087: * example.
088: *
089: * @throws StructureException if an error has occurred
090: */
091: public abstract void close() throws StructureException;
092:
093: /**
094: * Returns <code>true</code> if the structure is open, otherwise false.
095: *
096: * @return DOCUMENT ME!
097: */
098: public abstract boolean isOpen();
099:
100: /**
101: * Returns the number of elements stored in the structure.
102: *
103: * @return DOCUMENT ME!
104: *
105: * @throws StructureException if an error has occurred
106: */
107: public abstract int size() throws StructureException;
108:
109: /**
110: * Returns the name of the stored record.
111: *
112: * @return the name of the record as String
113: */
114: public abstract String getRecordName();
115:
116: /**
117: * Sets the name of the stored record.
118: *
119: * @param recordName DOCUMENT ME!
120: */
121: public abstract void setRecordName(String recordName);
122:
123: /**
124: * Returns whether this structure has at least one element or not. Should throw a {@link
125: * StructureException} if the structure is not open, for example.
126: *
127: * @return <code>true</code> if this structure is empty, otherwise <code>false</code>
128: *
129: * @throws StructureException if an error has occurred
130: */
131: public boolean isEmpty() throws StructureException {
132: return size() == 0;
133: }
134:
135: /**
136: * Set the root element of the structure. The root element and all its children will be saved
137: * in the extranaö structure. Should throw a {@link StructureException} if the structure is
138: * not open, for example.
139: *
140: * @param root the root element of the structure that should be saved.
141: *
142: * @throws StructureException if an error has occurred
143: */
144: public abstract void setRootElement(StructureElement root)
145: throws StructureException;
146:
147: /**
148: * Sets the record of the recordables. Should throw a {@link StructureException} if the
149: * structure is not open, for example.
150: *
151: * @param record the structure element to be stored
152: *
153: * @throws StructureException if an error has occurred
154: */
155: public abstract void setRecord(ReadAccessRecord record)
156: throws StructureException;
157:
158: /**
159: * Returns the root element of the structure. If there is no converter registered for a sort of
160: * xml elements, they will not be in the structure.
161: *
162: * @return root element of the structure
163: *
164: * @throws StructureException if the structure is not open
165: */
166: public abstract StructureElement getRootElement()
167: throws StructureException;
168:
169: /**
170: * Returns the record of the extrnal structure. If there is no converter registered for a sort
171: * of xml elements, they will not be in the structure.
172: *
173: * @return record of the extrnal structure
174: *
175: * @throws StructureException if the structure is not open
176: */
177: public abstract ReadAccessRecord getRecord()
178: throws StructureException;
179:
180: /**
181: * Adds a structure change listener to the list of structure change listeners. All listeners
182: * will be notified when this structure changes.
183: *
184: * @param listener the listener to add
185: */
186: public void addStructureChangeListener(
187: StructureChangeListener listener) {
188: structureChangeListeners.add(listener);
189: }
190:
191: /**
192: * Removes a structure change listener from the list of structure change listeners.
193: *
194: * @param listener the listener to remove
195: */
196: public void removeStructureChangeListener(
197: StructureChangeListener listener) {
198: structureChangeListeners.remove(listener);
199: }
200:
201: /**
202: * Specifies whether or not structure change listeners should be notified of structure changes.
203: *
204: * @param isNotificationEnabled DOCUMENT ME!
205: */
206: public void setNotificationEnabled(boolean isNotificationEnabled) {
207: this .isNotificationEnabled = isNotificationEnabled;
208: }
209:
210: /**
211: * Returns whether or not structure change listeners will be notified of structure changes.
212: *
213: * @return DOCUMENT ME!
214: */
215: public boolean isNotificationEnabled() {
216: return isNotificationEnabled;
217: }
218:
219: /**
220: * Fires a structure change (content or state) to all structure change listeners.
221: *
222: * @param event the event wich contains the information of the change
223: */
224: protected void fireStructureChange(StructureChangeEvent event) {
225: if (isNotificationEnabled) {
226: Iterator i = structureChangeListeners.iterator();
227:
228: while (i.hasNext()) {
229: ((StructureChangeListener) i.next())
230: .structureHasChanged(event);
231: }
232: }
233: }
234: }
|