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:
042: package org.netbeans.modules.vmd.inspector;
043:
044: import org.netbeans.modules.vmd.api.inspector.InspectorFolder;
045: import org.netbeans.modules.vmd.api.inspector.InspectorOrderingController;
046: import org.netbeans.modules.vmd.api.inspector.common.DefaultOrderingController;
047: import org.netbeans.modules.vmd.api.io.DataObjectContext;
048: import org.netbeans.modules.vmd.api.io.ProjectUtils;
049: import org.netbeans.modules.vmd.api.model.DesignComponent;
050: import org.netbeans.modules.vmd.api.model.DesignDocument;
051: import org.netbeans.modules.vmd.api.model.TypeID;
052: import org.netbeans.modules.vmd.api.model.common.AcceptSuggestion;
053: import org.openide.nodes.AbstractNode;
054:
055: import java.awt.datatransfer.Transferable;
056: import java.io.IOException;
057: import java.lang.ref.WeakReference;
058: import java.util.*;
059:
060: /**
061: *
062: * @author Karol Harezlak
063: */
064: final class InspectorFolderWrapper {
065:
066: private List<InspectorFolderWrapper> children;
067: private InspectorFolder folder;
068: private InspectorFolderNode node;
069: private WeakReference<DesignComponent> component;
070: private Collection<InspectorFolder> childrenFolders;
071: private Set<InspectorFolderWrapper> toRemove;
072: private Map<InspectorOrderingController, List<InspectorFolder>> ocMap;
073: private Map<Integer, List<InspectorFolder>> sortedLists;
074: private List<InspectorFolderWrapper> tempChildren;
075: private InspectorOrderingController defaultOrderingController;
076: private List<AbstractNode> childrenNode;
077: private WeakReference<DesignDocument> document;
078:
079: InspectorFolderWrapper(DesignDocument document,
080: InspectorFolder folder) {
081: this .folder = folder;
082: this .document = new WeakReference<DesignDocument>(document);
083: }
084:
085: List<InspectorFolderWrapper> getChildren() {
086: return children;
087: }
088:
089: List<AbstractNode> getChildrenNodes() {
090: if (children == null)
091: return null;
092:
093: if (childrenNode == null)
094: childrenNode = new ArrayList<AbstractNode>();
095: else
096: childrenNode.clear();
097:
098: for (InspectorFolderWrapper child : children) {
099: childrenNode.add(child.getNode());
100: }
101:
102: return childrenNode;
103: }
104:
105: boolean removeChild(InspectorFolder folder) {
106: if (children == null)
107: return false;
108: if (toRemove == null)
109: toRemove = new HashSet<InspectorFolderWrapper>();
110: else
111: toRemove.clear();
112: for (InspectorFolderWrapper child : children) {
113: if (child.getFolder().equals(folder))
114: toRemove.add(child);
115: }
116: if (toRemove == null || toRemove.isEmpty())
117: return false;
118: children.removeAll(toRemove);
119:
120: return true;
121: }
122:
123: InspectorFolder getFolder() {
124: return folder;
125: }
126:
127: void setChildren(List<InspectorFolderWrapper> children) {
128: if (children == null || this .children == children)
129: return;
130:
131: this .children = children;
132: if (childrenFolders == null)
133: childrenFolders = new ArrayList<InspectorFolder>();
134: else
135: childrenFolders.clear();
136: for (InspectorFolderWrapper wrapper : children) {
137: childrenFolders.add(wrapper.getFolder());
138: }
139: }
140:
141: InspectorFolderNode getNode() {
142: return node;
143: }
144:
145: DesignComponent getComponent() {
146: if (component == null)
147: return null;
148: return component.get();
149: }
150:
151: void resolveFolder(DesignDocument document) {
152: if (node == null) {
153: DataObjectContext dc = ProjectUtils
154: .getDataObjectContextForDocument(document);
155: if (dc != null) {
156: node = new InspectorFolderNode(dc);
157: } else
158: //TODO No Lookup for root node only
159: node = new InspectorFolderNode();
160: }
161: if (folder.getComponentID() != null)
162: component = new WeakReference<DesignComponent>(document
163: .getComponentByUID(folder.getComponentID()));
164: executeOrder();
165: getNode().resolveNode(this , document);
166: }
167:
168: Collection<InspectorFolder> getChildrenFolders() {
169: return childrenFolders;
170: }
171:
172: public AcceptSuggestion createSuggestion(Transferable transferable) {
173: return folder.createSuggestion(transferable);
174: }
175:
176: private void executeOrder() {
177: if (children == null || children.isEmpty())
178: return;
179:
180: if (ocMap == null)
181: ocMap = new HashMap<InspectorOrderingController, List<InspectorFolder>>();
182: else
183: ocMap.clear();
184:
185: if (sortedLists == null)
186: sortedLists = new TreeMap<Integer, List<InspectorFolder>>();
187: else
188: sortedLists.clear();
189:
190: if (tempChildren == null)
191: tempChildren = new ArrayList<InspectorFolderWrapper>();
192: else
193: tempChildren.clear();
194:
195: if (defaultOrderingController == null)
196: defaultOrderingController = new DefaultOrderingController(
197: Integer.MAX_VALUE, new TypeID(
198: TypeID.Kind.COMPONENT, "Default")); //NOI18N
199:
200: // sorting of descriptors based on TypeID
201: for (InspectorFolder fd : childrenFolders) {
202: boolean isWrite = false;
203: if (this .getFolder().getOrderingControllers() != null) {
204: for (InspectorOrderingController orderingController : this
205: .getFolder().getOrderingControllers()) {
206: if (orderingController.isTypeIDSupported(document
207: .get(), fd.getTypeID())
208: && ocMap.get(orderingController) == null) {
209: ocMap.put(orderingController,
210: new ArrayList<InspectorFolder>(Arrays
211: .asList(fd)));
212: isWrite = true;
213: } else if (orderingController.isTypeIDSupported(
214: document.get(), fd.getTypeID())
215: && ocMap.get(orderingController) != null) {
216: ocMap.get(orderingController).add(fd);
217: isWrite = true;
218: }
219: }
220: if (!isWrite
221: && ocMap.get(defaultOrderingController) == null)
222: ocMap.put(defaultOrderingController,
223: new ArrayList<InspectorFolder>(Arrays
224: .asList(fd)));
225: else if (!isWrite)
226: ocMap.get(defaultOrderingController).add(fd);
227: } else {
228: if (ocMap.get(defaultOrderingController) == null)
229: ocMap.put(defaultOrderingController,
230: new ArrayList<InspectorFolder>(Arrays
231: .asList(fd)));
232: else
233: ocMap.get(defaultOrderingController).add(fd);
234: }
235: }
236: for (InspectorOrderingController oc : ocMap.keySet()) {
237: List<InspectorFolder> sortedList;
238: if (component != null)
239: sortedList = oc.getOrdered(component.get(), Collections
240: .unmodifiableList(ocMap.get(oc)));
241: else
242: sortedList = oc.getOrdered(null, Collections
243: .unmodifiableList(ocMap.get(oc)));
244: if (sortedList == null)
245: throw new IllegalArgumentException(
246: "List returned from InspectorOrderingController is null, controller:"
247: + oc); //NOI18N
248:
249: //if (sortedList.size() != ocMap.get(oc).size() || (! ocMap.get(oc).containsAll(sortedList)))
250: // Debug.warning("Elements passed to sort in component: "+ component + " are diffrent from elements returned from FolderOrderingController :" + oc.getClass()); //NOI18N
251:
252: if (oc.getOrder() != null
253: && sortedLists.get(oc.getOrder()) == null)
254: sortedLists.put(oc.getOrder(), sortedList);
255: else if (oc.getOrder() != null
256: && sortedLists.get(oc.getOrder()) != null)
257: sortedLists.get(oc.getOrder()).addAll(sortedList);
258: }
259:
260: childrenFolders.clear();
261:
262: for (List<InspectorFolder> fdList : sortedLists.values()) {
263: childrenFolders.addAll(fdList);
264: }
265:
266: for (InspectorFolder fd : childrenFolders) {
267: for (InspectorFolderWrapper wrapper : children) {
268: if (wrapper.getFolder() == fd
269: && fd.getComponentID().equals(
270: wrapper.getFolder().getComponentID()))
271: tempChildren.add(wrapper);
272: }
273: }
274:
275: children = new ArrayList<InspectorFolderWrapper>(tempChildren);
276: }
277:
278: void terminate() {
279: folder = null;
280: if (node != null) {
281: node.terminate();
282: try {
283: node.destroy();
284: } catch (IOException ex) {
285: ex.printStackTrace();
286: }
287: }
288: node = null;
289: component = null;
290: childrenFolders = null;
291: toRemove = null;
292: ocMap = null;
293: sortedLists = null;
294: tempChildren = null;
295: defaultOrderingController = null;
296: childrenNode = null;
297: if (children == null)
298: return;
299: for (InspectorFolderWrapper wrapper : children) {
300: wrapper.terminate();
301: }
302: children = null;
303: }
304:
305: public String toString() {
306: StringBuffer buffer = new StringBuffer().append("[ ")
307: // NOI18N
308: .append(folder.getDisplayName()).append(" ] TYPE : ")
309: // NOI18N
310: .append(folder.getTypeID()).append(", ID : ")
311: //NOI18N
312: .append(folder.getComponentID())
313: .append(", Children : ") // NOI18N
314: .append(children == null ? 0 : children.size()).append(
315: " " + super.toString());
316: return buffer.toString();
317: }
318:
319: }
|