001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.tax;
042:
043: import org.netbeans.tax.event.TreeEventManager;
044:
045: import org.netbeans.tax.spec.DocumentFragment;
046: import org.netbeans.tax.spec.DTD;
047:
048: /**
049: * It may contain <b>multiple "root elements"</b> because it must be placed somewhere
050: * anyway.
051: * <p>It maps to external entities.
052: *
053: * @author Libor Kramolis
054: * @version 0.1
055: */
056: public class TreeDocumentFragment extends AbstractTreeDocument
057: implements TreeDocumentRoot {
058: /** */
059: public static final String PROP_VERSION = "version"; // NOI18N
060: /** */
061: public static final String PROP_ENCODING = "encoding"; // NOI18N
062:
063: /** Own event manager. */
064: private TreeEventManager eventManager;
065:
066: /** -- can be null. */
067: private String version;
068:
069: /** -- can be null. */
070: private String encoding;
071:
072: //
073: // init
074: //
075:
076: /**
077: * Creates new TreeDocumentFragment.
078: * @throws InvalidArgumentException
079: */
080: public TreeDocumentFragment(String version, String encoding)
081: throws InvalidArgumentException {
082: super ();
083:
084: checkVersion(version);
085: checkEncoding(encoding);
086: checkHeader(version, encoding);
087:
088: this .version = version;
089: this .encoding = encoding;
090: this .eventManager = new TreeEventManager();
091: }
092:
093: /**
094: * Creates new TreeDocumentFragment.
095: * @throws InvalidArgumentException
096: */
097: public TreeDocumentFragment() throws InvalidArgumentException {
098: this (null, null); // Q: is it valid? A: yes, header is not mandatory
099: }
100:
101: /** Creates new TreeDocumentFragment -- copy constructor. */
102: protected TreeDocumentFragment(
103: TreeDocumentFragment documentFragment, boolean deep) {
104: super (documentFragment, deep);
105:
106: this .version = documentFragment.version;
107: this .encoding = documentFragment.encoding;
108: this .eventManager = new TreeEventManager(
109: documentFragment.eventManager);
110: }
111:
112: //
113: // from TreeObject
114: //
115:
116: /**
117: */
118: public Object clone(boolean deep) {
119: return new TreeDocumentFragment(this , deep);
120: }
121:
122: /**
123: */
124: public boolean equals(Object object, boolean deep) {
125: if (!!!super .equals(object, deep))
126: return false;
127:
128: TreeDocumentFragment peer = (TreeDocumentFragment) object;
129: if (!!!Util.equals(this .getVersion(), peer.getVersion()))
130: return false;
131: if (!!!Util.equals(this .getEncoding(), peer.getEncoding()))
132: return false;
133:
134: return true;
135: }
136:
137: /*
138: * Merges version and encoding properties
139: */
140: public void merge(TreeObject treeObject)
141: throws CannotMergeException {
142: super .merge(treeObject);
143:
144: TreeDocumentFragment peer = (TreeDocumentFragment) treeObject;
145:
146: try {
147: setVersionImpl(peer.getVersion());
148: setEncodingImpl(peer.getEncoding());
149: } catch (Exception exc) {
150: throw new CannotMergeException(treeObject, exc);
151: }
152: }
153:
154: //
155: // from TreeDocumentRoot
156: //
157:
158: /**
159: */
160: public String getVersion() {
161: return version;
162: }
163:
164: /**
165: */
166: private final void setVersionImpl(String newVersion) {
167: String oldVersion = this .version;
168:
169: this .version = newVersion;
170:
171: firePropertyChange(PROP_VERSION, oldVersion, newVersion);
172: }
173:
174: /**
175: * @throws ReadOnlyException
176: * @throws InvalidArgumentException
177: */
178: public final void setVersion(String newVersion)
179: throws ReadOnlyException, InvalidArgumentException {
180: //
181: // check new value
182: //
183: if (Util.equals(this .version, newVersion))
184: return;
185: checkReadOnly();
186: checkVersion(newVersion);
187: checkHeader(newVersion, this .encoding);
188:
189: //
190: // set new value
191: //
192: setVersionImpl(newVersion);
193: }
194:
195: /**
196: */
197: protected final void checkVersion(String version)
198: throws InvalidArgumentException {
199: TreeUtilities.checkDocumentFragmentVersion(version);
200: }
201:
202: /**
203: */
204: public String getEncoding() {
205: return encoding;
206: }
207:
208: /**
209: */
210: private void setEncodingImpl(String newEncoding) {
211: String oldEncoding = this .encoding;
212:
213: this .encoding = newEncoding;
214:
215: firePropertyChange(PROP_ENCODING, oldEncoding, newEncoding);
216: }
217:
218: /**
219: * @throws ReadOnlyException
220: * @throws InvalidArgumentException
221: */
222: public final void setEncoding(String newEncoding)
223: throws ReadOnlyException, InvalidArgumentException {
224: //
225: // check new value
226: //
227: if (Util.equals(this .encoding, newEncoding))
228: return;
229: checkReadOnly();
230: checkEncoding(newEncoding);
231: checkHeader(this .version, newEncoding);
232:
233: //
234: // set new value
235: //
236: setEncodingImpl(newEncoding);
237: }
238:
239: /**
240: */
241: protected final void checkEncoding(String encoding)
242: throws InvalidArgumentException {
243: TreeUtilities.checkDocumentFragmentEncoding(encoding);
244: }
245:
246: /**
247: * @throws ReadOnlyException
248: * @throws InvalidArgumentException
249: */
250: public final void setHeader(String newVersion, String newEncoding)
251: throws ReadOnlyException, InvalidArgumentException {
252: //
253: // check new value
254: //
255: boolean setVersion = !!!Util.equals(this .version, newVersion);
256: boolean setEncoding = !!!Util
257: .equals(this .encoding, newEncoding);
258: if (!!!setVersion && !!!setEncoding) {
259: return;
260: }
261: checkReadOnly();
262: if (setVersion) {
263: checkVersion(newVersion);
264: }
265: if (setEncoding) {
266: checkEncoding(newEncoding);
267: }
268: checkHeader(newVersion, newEncoding);
269:
270: //
271: // set new value
272: //
273: if (setVersion) {
274: setVersionImpl(newVersion);
275: }
276: if (setEncoding) {
277: setEncodingImpl(newEncoding);
278: }
279: }
280:
281: /**
282: */
283: protected final void checkHeader(String version, String encoding)
284: throws InvalidArgumentException {
285: if ((version != null) && (encoding == null)) {
286: throw new InvalidArgumentException(Util.THIS
287: .getString("EXC_invalid_document_fragment_header"),
288: new NullPointerException());
289: }
290: }
291:
292: //
293: // event model
294: //
295:
296: /**
297: */
298: public TreeEventManager getRootEventManager() {
299: return eventManager;
300: }
301:
302: //
303: // TreeObjectList.ContentManager
304: //
305:
306: /**
307: */
308: protected TreeObjectList.ContentManager createChildListContentManager() {
309: return new ChildListContentManager();
310: }
311:
312: /**
313: *
314: */
315: protected class ChildListContentManager extends
316: AbstractTreeDocument.ChildListContentManager {
317:
318: /**
319: */
320: public TreeNode getOwnerNode() {
321: return TreeDocumentFragment.this ;
322: }
323:
324: /**
325: */
326: public void checkAssignableObject(Object obj) {
327: super .checkAssignableObject(obj);
328: checkAssignableClass(DocumentFragment.Child.class, obj);
329: }
330:
331: } // end: class ChildListContentManager
332:
333: }
|