KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > mimelookup > impl > CompoundFolderChildren


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.editor.mimelookup.impl;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.beans.PropertyChangeSupport JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.logging.Level JavaDoc;
33 import java.util.logging.Logger JavaDoc;
34 import org.openide.filesystems.FileObject;
35 import org.openide.util.TopologicalSortException;
36 import org.openide.util.Utilities;
37
38 /**
39  *
40  * @author vita
41  */

42 public final class CompoundFolderChildren {
43
44     public static final String JavaDoc PROP_CHILDREN = "FolderChildren.PROP_CHILDREN"; //NOI18N
45

46     private static final String JavaDoc HIDDEN_SUFFIX = "_hidden"; //NOI18N
47
private static final String JavaDoc HIDDEN_ATTR_NAME = "hidden"; //NOI18N
48

49     private static final Logger JavaDoc LOG = Logger.getLogger(CompoundFolderChildren.class.getName());
50     
51     private final String JavaDoc LOCK = new String JavaDoc("CompoundFolderChildren.LOCK"); //NOI18N
52
private FolderChildren [] layers = null;
53     private List JavaDoc children = Collections.EMPTY_LIST;
54     
55     private PCL listener = new PCL();
56     private PropertyChangeSupport JavaDoc pcs = new PropertyChangeSupport JavaDoc(this);
57
58     public CompoundFolderChildren(String JavaDoc [] paths) {
59         this(paths, true);
60     }
61     
62     /** Creates a new instance of FolderPathLookup */
63     public CompoundFolderChildren(String JavaDoc [] paths, boolean includeSubfolders) {
64         this.layers = new FolderChildren [paths.length];
65         for (int i = 0; i < paths.length; i++) {
66             this.layers[i] = new FolderChildren(paths[i], includeSubfolders);
67             this.layers[i].addPropertyChangeListener(listener);
68         }
69         
70         rebuild();
71     }
72     
73     public List JavaDoc getChildren() {
74         synchronized (LOCK) {
75             return children;
76         }
77     }
78     
79     public void addPropertyChangeListener(PropertyChangeListener JavaDoc l) {
80         pcs.addPropertyChangeListener(l);
81     }
82     
83     public void removePropertyChangeListener(PropertyChangeListener JavaDoc l) {
84         pcs.removePropertyChangeListener(l);
85     }
86     
87     private void rebuild() {
88         PropertyChangeEvent JavaDoc event = null;
89         
90         synchronized (LOCK) {
91             // Collect all children
92
HashMap JavaDoc visible = new HashMap JavaDoc();
93             HashMap JavaDoc hidden = new HashMap JavaDoc();
94             
95             for (int i = 0; i < layers.length; i++) {
96                 List JavaDoc layerKids = layers[i].getChildren();
97                 for (Iterator JavaDoc j = layerKids.iterator(); j.hasNext(); ) {
98                     FileObject f = (FileObject) j.next();
99                     String JavaDoc name = realName(f);
100                     
101                     if (isHidden(f)) {
102                         if (!hidden.containsKey(name)) {
103                             hidden.put(name, f);
104                         }
105                     }
106
107                     if (!hidden.containsKey(name)) {
108                         if (!visible.containsKey(name)) {
109                             visible.put(name, f);
110                         }
111                     }
112                 }
113             }
114
115             // Collect all edges
116
HashMap JavaDoc edges = new HashMap JavaDoc();
117             for (int i = 0; i < layers.length; i++) {
118                 Map JavaDoc layerAttrs = layers[i].getFolderAttributes();
119                 for (Iterator JavaDoc j = layerAttrs.keySet().iterator(); j.hasNext(); ) {
120                     String JavaDoc attrName = (String JavaDoc) j.next();
121                     Object JavaDoc attrValue = layerAttrs.get(attrName);
122                     
123                     // Check whether the attribute affects sorting
124
int slashIdx = attrName.indexOf('/'); //NOI18N
125
if (slashIdx == -1 || !(attrValue instanceof Boolean JavaDoc)) {
126                         continue;
127                     }
128
129                     // Get the file names
130
String JavaDoc name1 = attrName.substring(0, slashIdx);
131                     String JavaDoc name2 = attrName.substring(slashIdx + 1);
132                     if (!((Boolean JavaDoc) attrValue).booleanValue()) {
133                         // Swap the names
134
String JavaDoc s = name1;
135                         name1 = name2;
136                         name2 = s;
137                     }
138                     
139                     // Get the files and add them among the edges
140
FileObject from = (FileObject) visible.get(name1);
141                     FileObject to = (FileObject) visible.get(name2);
142                     
143                     if (from != null && to != null) {
144                         HashSet JavaDoc vertices = (HashSet JavaDoc) edges.get(from);
145                         if (vertices == null) {
146                             vertices = new HashSet JavaDoc();
147                             edges.put(from, vertices);
148                         }
149                         vertices.add(to);
150                     }
151                 }
152             }
153             
154             // Sort the children
155
List JavaDoc sorted;
156             
157             try {
158                 sorted = Utilities.topologicalSort(visible.values(), edges);
159             } catch (TopologicalSortException e) {
160                 LOG.log(Level.WARNING, "Can't sort folder children.", e); //NOI18N
161
sorted = e.partialSort();
162             }
163             
164             if (!children.equals(sorted)) {
165                 event = new PropertyChangeEvent JavaDoc(this, PROP_CHILDREN, children, sorted);
166                 children = sorted;
167             }
168         }
169         
170         if (event != null) {
171             pcs.firePropertyChange(event);
172         }
173     }
174
175     private boolean isHidden(FileObject fo) {
176         if (fo.getNameExt().endsWith(HIDDEN_SUFFIX)) {
177             return true;
178         }
179         
180         for (Enumeration JavaDoc e = fo.getAttributes(); e.hasMoreElements(); ) {
181             String JavaDoc name = (String JavaDoc)e.nextElement();
182             if (HIDDEN_ATTR_NAME.equals(name)) {
183                 Object JavaDoc value = fo.getAttribute(name);
184                 if ((value instanceof Boolean JavaDoc) && ((Boolean JavaDoc) value).booleanValue()){
185                     return true;
186                 }
187             }
188         }
189         
190         return false;
191     }
192     
193     private String JavaDoc realName(FileObject fo) {
194         String JavaDoc nameExt = fo.getNameExt();
195         if (nameExt.endsWith(HIDDEN_SUFFIX)) {
196             return nameExt.substring(0, nameExt.length() - HIDDEN_SUFFIX.length());
197         } else {
198             return nameExt;
199         }
200     }
201     
202     private class PCL implements PropertyChangeListener JavaDoc {
203         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
204             // TODO: This should be optimized for ignoring changes coming from a layer,
205
// which didn't contribute the file in the final result.
206
if (evt.getPropertyName() != null &&
207                 FolderChildren.PROP_CHILD_CHANGED.equals(evt.getPropertyName()))
208             {
209                 // The content of a child changed
210
pcs.firePropertyChange(new PropertyChangeEvent JavaDoc(CompoundFolderChildren.this, PROP_CHILDREN, null, null));
211             } else {
212                 // The list of children or their sorting changed
213
rebuild();
214             }
215         }
216
217     } // End of FolderListener class
218
}
219
Popular Tags