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 General
007: * Public License Version 2 only ("GPL") or the Common Development and Distribution
008: * License("CDDL") (collectively, the "License"). You may not use this file except in
009: * compliance with the License. You can obtain a copy of the License at
010: * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
011: * License for the specific language governing permissions and limitations under the
012: * License. When distributing the software, include this License Header Notice in
013: * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun
014: * designates this particular file as subject to the "Classpath" exception as
015: * provided by Sun in the GPL Version 2 section of the License file that
016: * accompanied this code. If applicable, add the following below the License Header,
017: * with the fields enclosed by brackets [] replaced by your own identifying
018: * information: "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Contributor(s):
021: *
022: * The Original Software is NetBeans. The Initial Developer of the Original Software
023: * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
024: * Rights Reserved.
025: *
026: * If you wish your version of this file to be governed by only the CDDL or only the
027: * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
028: * this software in this distribution under the [CDDL or GPL Version 2] license." If
029: * you do not indicate a single choice of license, a recipient has the option to
030: * distribute your version of this file under either the CDDL, the GPL Version 2 or
031: * to extend the choice of license to its licensees as provided above. However, if
032: * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
033: * the option applies only if the new code is made subject to such option by the
034: * copyright holder.
035: */
036:
037: package org.netbeans.installer.product;
038:
039: import java.io.File;
040: import java.util.ArrayList;
041: import java.util.Date;
042: import java.util.HashMap;
043: import java.util.LinkedList;
044: import java.util.List;
045: import java.util.Locale;
046: import java.util.Map;
047: import java.util.Properties;
048: import javax.swing.Icon;
049: import javax.swing.ImageIcon;
050: import javax.swing.tree.TreePath;
051: import org.netbeans.installer.product.filters.RegistryFilter;
052: import org.netbeans.installer.product.filters.TrueFilter;
053: import org.netbeans.installer.utils.FileProxy;
054: import org.netbeans.installer.utils.StringUtils;
055: import org.netbeans.installer.utils.XMLUtils;
056: import org.netbeans.installer.utils.exceptions.DownloadException;
057: import org.netbeans.installer.utils.exceptions.FinalizationException;
058: import org.netbeans.installer.utils.exceptions.InitializationException;
059: import org.netbeans.installer.utils.exceptions.ParseException;
060: import org.netbeans.installer.utils.helper.ExtendedUri;
061: import org.netbeans.installer.utils.helper.NbiProperties;
062: import org.netbeans.installer.utils.helper.PropertyContainer;
063: import org.netbeans.installer.utils.helper.UiMode;
064: import org.w3c.dom.Document;
065: import org.w3c.dom.Element;
066:
067: /**
068: *
069: * @author Kirill Sorokin
070: */
071: public abstract class RegistryNode implements PropertyContainer {
072: protected RegistryNode parent;
073:
074: protected RegistryType registryType;
075:
076: protected String uid;
077:
078: protected ExtendedUri iconUri;
079: protected Icon icon;
080:
081: protected long offset;
082: protected boolean expand;
083: protected boolean initialVisible;
084: protected boolean currentVisible;
085:
086: protected Date built;
087:
088: protected Map<Locale, String> displayNames;
089: protected Map<Locale, String> descriptions;
090:
091: protected List<RegistryNode> children;
092:
093: protected NbiProperties properties;
094:
095: protected RegistryNode() {
096: initialVisible = true;
097: currentVisible = true;
098: built = new Date();
099:
100: displayNames = new HashMap<Locale, String>();
101: descriptions = new HashMap<Locale, String>();
102:
103: children = new ArrayList<RegistryNode>();
104:
105: properties = new NbiProperties();
106: }
107:
108: public String getUid() {
109: return uid;
110: }
111:
112: public String getDisplayName() {
113: return getDisplayName(Locale.getDefault());
114: }
115:
116: public String getDisplayName(final Locale locale) {
117: return StringUtils.getLocalizedString(displayNames, locale);
118: }
119:
120: public Map<Locale, String> getDisplayNames() {
121: return displayNames;
122: }
123:
124: public void setDisplayName(final String displayName) {
125: setDisplayName(Locale.getDefault(), displayName);
126: }
127:
128: public void setDisplayName(final Locale locale,
129: final String displayName) {
130: displayNames.put(locale, displayName);
131: }
132:
133: public String getDescription() {
134: return getDescription(Locale.getDefault());
135: }
136:
137: public String getDescription(final Locale locale) {
138: return StringUtils.getLocalizedString(descriptions, locale);
139: }
140:
141: public Map<Locale, String> getDescriptions() {
142: return descriptions;
143: }
144:
145: public void setDescription(final String description) {
146: setDescription(Locale.getDefault(), description);
147: }
148:
149: public void setDescription(final Locale locale,
150: final String description) {
151: descriptions.put(locale, description);
152: }
153:
154: public ExtendedUri getIconUri() {
155: return iconUri;
156: }
157:
158: public Icon getIcon() {
159: if (icon == null && UiMode.getCurrentUiMode() != UiMode.SILENT) {
160: if (getIconUri() != null && getIconUri().getLocal() != null) {
161: icon = new ImageIcon(getIconUri().getLocal().getPath());
162: }
163: }
164: return icon;
165: }
166:
167: public long getOffset() {
168: return offset;
169: }
170:
171: public boolean isVisible() {
172: return currentVisible;
173: }
174:
175: public void setVisible(final boolean visible) {
176: this .currentVisible = visible;
177: }
178:
179: public boolean getExpand() {
180: return expand;
181: }
182:
183: public Date getBuildDate() {
184: return built;
185: }
186:
187: public RegistryType getRegistryType() {
188: return registryType;
189: }
190:
191: public void setRegistryType(final RegistryType registryType) {
192: this .registryType = registryType;
193: }
194:
195: // tree /////////////////////////////////////////////////////////////////////////
196: public RegistryNode getParent() {
197: return parent;
198: }
199:
200: public void setParent(final RegistryNode parent) {
201: this .parent = parent;
202: }
203:
204: public List<RegistryNode> getChildren() {
205: return children;
206: }
207:
208: public List<RegistryNode> getVisibleChildren() {
209: List<RegistryNode> visibleChildren = new LinkedList<RegistryNode>();
210:
211: for (RegistryNode child : children) {
212: if (child.isVisible()) {
213: visibleChildren.add(child);
214: }
215: }
216:
217: return visibleChildren;
218: }
219:
220: public void addChild(final RegistryNode child) {
221: child.setParent(this );
222:
223: int i;
224: for (i = 0; i < children.size(); i++) {
225: if (children.get(i).getOffset() > child.getOffset()) {
226: break;
227: }
228: }
229: children.add(i, child);
230: }
231:
232: public void removeChild(final RegistryNode child) {
233: children.remove(child);
234: }
235:
236: public void attachRegistry(Registry registry) {
237: for (RegistryNode node : registry.getRegistryRoot()
238: .getChildren()) {
239: addChild(node);
240: }
241: }
242:
243: public boolean isAncestor(final RegistryNode candidate) {
244: for (RegistryNode node : getChildren()) {
245: if ((node == candidate) || node.isAncestor(candidate)) {
246: return true;
247: }
248: }
249:
250: return false;
251: }
252:
253: public boolean isAncestor(
254: final List<? extends RegistryNode> candidates) {
255: for (RegistryNode node : candidates) {
256: if (isAncestor(node)) {
257: return true;
258: }
259: }
260:
261: return false;
262: }
263:
264: public boolean hasChildren() {
265: return hasChildren(new TrueFilter());
266: }
267:
268: public boolean hasChildren(RegistryFilter filter) {
269: for (RegistryNode child : children) {
270: if (filter.accept(child)) {
271: return true;
272: }
273:
274: if (child.hasChildren(filter)) {
275: return true;
276: }
277: }
278:
279: return false;
280: }
281:
282: public TreePath getTreePath() {
283: List<RegistryNode> nodes = new LinkedList<RegistryNode>();
284:
285: RegistryNode node = this ;
286: while (node != null) {
287: nodes.add(0, node);
288: node = node.getParent();
289: }
290:
291: return new TreePath(nodes.toArray());
292: }
293:
294: // properties ///////////////////////////////////////////////////////////////////
295: public Properties getProperties() {
296: return properties;
297: }
298:
299: public String getProperty(final String name) {
300: return properties.getProperty(name);
301: }
302:
303: public void setProperty(final String name, final String value) {
304: properties.setProperty(name, value);
305: }
306:
307: // node <-> dom /////////////////////////////////////////////////////////////////
308: public Element saveToDom(Document document, RegistryFilter filter)
309: throws FinalizationException {
310: final boolean hasChilren = hasChildren(filter);
311:
312: if (filter.accept(this ) || hasChilren) {
313: Element element = saveToDom(document
314: .createElement(getTagName()));
315:
316: if (hasChilren) {
317: element
318: .appendChild(saveChildrenToDom(document, filter));
319: }
320:
321: return element;
322: } else {
323: return null;
324: }
325: }
326:
327: public Element saveChildrenToDom(Document document,
328: RegistryFilter filter) throws FinalizationException {
329: Element components = null;
330:
331: if (hasChildren(filter)) {
332: components = document.createElement("components");
333:
334: for (RegistryNode child : children) {
335: if (filter.accept(child) || child.hasChildren(filter)) {
336: components.appendChild(child.saveToDom(document,
337: filter));
338: }
339: }
340: }
341:
342: return components;
343: }
344:
345: protected String getTagName() {
346: return "node";
347: }
348:
349: protected Element saveToDom(final Element element)
350: throws FinalizationException {
351: Document document = element.getOwnerDocument();
352:
353: element.setAttribute("uid", uid);
354: element.setAttribute("offset", Long.toString(offset));
355: element.setAttribute("expand", Boolean.toString(expand));
356: element.setAttribute("visible", Boolean
357: .toString(initialVisible));
358:
359: element.setAttribute("built", Long.toString(built.getTime()));
360:
361: element.appendChild(XMLUtils.saveLocalizedString(displayNames,
362: document.createElement("display-name")));
363:
364: element.appendChild(XMLUtils.saveLocalizedString(descriptions,
365: document.createElement("description")));
366:
367: element.appendChild(XMLUtils.saveExtendedUri(iconUri, document
368: .createElement("icon")));
369:
370: if (properties.size() > 0) {
371: element.appendChild(XMLUtils.saveNbiProperties(properties,
372: document.createElement("properties")));
373: }
374:
375: return element;
376: }
377:
378: public RegistryNode loadFromDom(final Element element)
379: throws InitializationException {
380: try {
381: uid = element.getAttribute("uid");
382:
383: iconUri = XMLUtils.parseExtendedUri(XMLUtils.getChild(
384: element, "icon"));
385:
386: if (!Boolean.getBoolean(Registry.LAZY_LOAD_ICONS_PROPERTY)) {
387: final File iconFile = FileProxy.getInstance().getFile(
388: iconUri.getRemote());
389: iconUri.setLocal(iconFile.toURI());
390: }
391:
392: offset = Long.parseLong(element.getAttribute("offset"));
393: currentVisible = initialVisible = Boolean
394: .parseBoolean(element.getAttribute("visible"));
395: expand = Boolean.parseBoolean(element
396: .getAttribute("expand"));
397:
398: built = new Date(Long.parseLong(element
399: .getAttribute("built")));
400:
401: displayNames = XMLUtils.parseLocalizedString(XMLUtils
402: .getChild(element, "display-name"));
403:
404: descriptions = XMLUtils.parseLocalizedString(XMLUtils
405: .getChild(element, "description"));
406:
407: properties = XMLUtils.parseNbiProperties(XMLUtils.getChild(
408: element, "properties"));
409: } catch (ParseException e) {
410: throw new InitializationException(
411: "Cannot deserialize product tree node", e);
412: } catch (DownloadException e) {
413: throw new InitializationException(
414: "Cannot deserialize product tree node", e);
415: } catch (NumberFormatException e) {
416: throw new InitializationException(
417: "Cannot deserialize product tree node", e);
418: }
419:
420: return this ;
421: }
422:
423: // node -> string ///////////////////////////////////////////////////////////////
424: @Override
425: public String toString() {
426: return getDisplayName();
427: }
428: }
|