KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > project > ui > SuiteOperations


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.apisupport.project.ui;
21
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collections 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.Set JavaDoc;
33 import javax.swing.Action JavaDoc;
34 import org.apache.tools.ant.module.api.support.ActionUtils;
35 import org.netbeans.api.project.FileOwnerQuery;
36 import org.netbeans.api.project.Project;
37 import org.netbeans.api.project.ProjectManager;
38 import org.netbeans.api.project.ProjectUtils;
39 import org.netbeans.api.project.ui.OpenProjects;
40 import org.netbeans.api.queries.VisibilityQuery;
41 import org.netbeans.modules.apisupport.project.NbModuleProject;
42 import org.netbeans.modules.apisupport.project.suite.BrandingSupport;
43 import org.netbeans.modules.apisupport.project.suite.SuiteProject;
44 import org.netbeans.modules.apisupport.project.ui.customizer.BasicBrandingModel;
45 import org.netbeans.modules.apisupport.project.ui.customizer.SuiteProperties;
46 import org.netbeans.modules.apisupport.project.ui.customizer.SuiteUtils;
47 import org.netbeans.spi.project.ActionProvider;
48 import org.netbeans.spi.project.DeleteOperationImplementation;
49 import org.netbeans.spi.project.MoveOperationImplementation;
50 import org.netbeans.spi.project.SubprojectProvider;
51 import org.netbeans.spi.project.support.ProjectOperations;
52 import org.netbeans.spi.project.support.ant.AntProjectHelper;
53 import org.netbeans.spi.project.support.ant.EditableProperties;
54 import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
55 import org.netbeans.spi.project.ui.support.CommonProjectActions;
56 import org.openide.LifecycleManager;
57 import org.openide.filesystems.FileObject;
58 import org.openide.filesystems.FileUtil;
59 import org.openide.util.ContextAwareAction;
60 import org.openide.util.Mutex;
61 import org.openide.util.MutexException;
62 import org.openide.util.lookup.Lookups;
63
64 /**
65  * @author Martin Krauskopf
66  */

67 public final class SuiteOperations implements DeleteOperationImplementation,
68         MoveOperationImplementation {
69     
70     private static final Map JavaDoc<String JavaDoc,Set JavaDoc<NbModuleProject>> TEMPORARY_CACHE = new HashMap JavaDoc();
71     
72     private final SuiteProject suite;
73     private final FileObject projectDir;
74     
75     public SuiteOperations(final SuiteProject suite) {
76         this.suite = suite;
77         this.projectDir = suite.getProjectDirectory();
78     }
79     
80     public void notifyDeleting() throws IOException JavaDoc {
81         FileObject buildXML = projectDir.getFileObject(GeneratedFilesHelper.BUILD_XML_PATH);
82         ActionUtils.runTarget(buildXML, new String JavaDoc[] { ActionProvider.COMMAND_CLEAN }, null).waitFinished();
83         
84         // remove all suite components from the suite - i.e. make them standalone
85
SubprojectProvider spp = (SubprojectProvider) suite.getLookup().lookup(SubprojectProvider.class);
86         for (Iterator JavaDoc it = spp.getSubprojects().iterator(); it.hasNext();) {
87             NbModuleProject suiteComponent = (NbModuleProject) it.next();
88             SuiteUtils.removeModuleFromSuite(suiteComponent);
89         }
90     }
91     
92     public void notifyDeleted() throws IOException JavaDoc {
93         suite.getHelper().notifyDeleted();
94     }
95     
96     public void notifyMoving() throws IOException JavaDoc {
97         Set JavaDoc<NbModuleProject> subprojects = SuiteUtils.getSubProjects(suite);
98         if (!subprojects.isEmpty()) {
99             // XXX using suite's name is probably weak. Consider another solution. E.g.
100
// store some "private" property and than read it.
101
TEMPORARY_CACHE.put(ProjectUtils.getInformation(suite).getName(), subprojects);
102         }
103         // this will temporarily remove all suite components - this is needed
104
// to prevent infrastructure confusion about lost suite. They will be
105
// readded in the notifyMoved.
106
notifyDeleting();
107     }
108     
109     public void notifyMoved(Project original, File JavaDoc originalPath, String JavaDoc nueName) throws IOException JavaDoc {
110         if (original == null) { // called on the original project
111
suite.getHelper().notifyDeleted();
112         } else { // called on the new project
113
String JavaDoc name = ProjectUtils.getInformation(suite).getName();
114             Set JavaDoc<Project> subprojects = (Set JavaDoc) TEMPORARY_CACHE.remove(name);
115             if (subprojects != null) {
116                 Set JavaDoc toOpen = new HashSet JavaDoc();
117                 for (Iterator JavaDoc it = subprojects.iterator(); it.hasNext();) {
118                     NbModuleProject originalComp = (NbModuleProject) it.next();
119                     
120                     boolean directoryChanged = !original.getProjectDirectory().
121                             equals(suite.getProjectDirectory());
122                     if (directoryChanged && FileUtil.isParentOf( // wasRelative
123
original.getProjectDirectory(), originalComp.getProjectDirectory())) {
124                         boolean isOpened = SuiteOperations.isOpened(originalComp);
125                         Project nueComp = SuiteOperations.moveModule(originalComp, suite.getProjectDirectory());
126                         SuiteUtils.addModule(suite, (NbModuleProject) nueComp);
127                         if (isOpened) {
128                             toOpen.add(nueComp);
129                         }
130                     } else {
131                         SuiteUtils.addModule(suite, originalComp);
132                     }
133                 }
134                 OpenProjects.getDefault().open((Project[]) toOpen.toArray(new Project[toOpen.size()]), false);
135             }
136             boolean isRename = original.getProjectDirectory().getParent().equals(
137                     suite.getProjectDirectory().getParent());
138             if (isRename) {
139                 setDisplayName(nueName);
140             }
141             FileObject origSuiteFO = FileUtil.toFileObject(originalPath);
142             if (origSuiteFO != null && origSuiteFO.getChildren().length == 0) {
143                 origSuiteFO.delete();
144             }
145         }
146     }
147     
148     public List JavaDoc<FileObject> getMetadataFiles() {
149         List JavaDoc<FileObject> files = new ArrayList JavaDoc();
150         addFile(GeneratedFilesHelper.BUILD_XML_PATH, files);
151         addFile("nbproject", files); // NOI18N
152
addFile(".cvsignore", files); // NOI18N
153
return files;
154     }
155     
156     public List JavaDoc<FileObject> getDataFiles() {
157         List JavaDoc<FileObject> files = new ArrayList JavaDoc();
158         addFile(suite.getEvaluator().getProperty(BrandingSupport.BRANDING_DIR_PROPERTY), files);
159         return files;
160     }
161     
162     private void addFile(String JavaDoc fileName, List JavaDoc<FileObject> result) {
163         FileObject file = projectDir.getFileObject(fileName);
164         if (file != null) {
165             result.add(file);
166         }
167     }
168     
169     private void setDisplayName(final String JavaDoc nueName) throws IOException JavaDoc {
170         final SuiteProperties sp = new SuiteProperties(suite, suite.getHelper(),
171                 suite.getEvaluator(), SuiteUtils.getSubProjects(suite));
172         final BasicBrandingModel branding = sp.getBrandingModel();
173         try {
174             ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction() {
175                 public Object JavaDoc run() throws IOException JavaDoc {
176                     if (branding.isBrandingEnabled()) { // application
177
branding.setTitle(nueName);
178                         sp.storeProperties();
179                     } else { // ordinary suite of modules
180
EditableProperties props = suite.getHelper().getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
181                         props.setProperty(BasicBrandingModel.TITLE_PROPERTY, nueName);
182                         suite.getHelper().putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
183                     }
184                     ProjectManager.getDefault().saveProject(suite);
185                     return null;
186                 }
187             });
188         } catch (MutexException e) {
189             throw (IOException JavaDoc) e.getException();
190         }
191     }
192     
193     /** Package private for unit tests <strong>only</strong>. */
194     static Project moveModule(final NbModuleProject original, final FileObject targetParent) throws IOException JavaDoc, IllegalArgumentException JavaDoc {
195         ProjectOperations.notifyMoving(original);
196         SuiteOperations.close(original);
197         FileObject origDir = original.getProjectDirectory();
198         FileObject copy = doCopy(original, origDir, targetParent);
199         ProjectManager.getDefault().clearNonProjectCache();
200         Project nueComp = ProjectManager.getDefault().findProject(copy);
201         assert nueComp != null;
202         File JavaDoc originalPath = FileUtil.toFile(origDir);
203         doDelete(original, origDir);
204         ProjectOperations.notifyMoved(original, nueComp, originalPath, originalPath.getName());
205         return nueComp;
206     }
207     
208     private static boolean isOpened(final Project original) {
209         boolean opened = false;
210         Project[] openProjects = OpenProjects.getDefault().getOpenProjects();
211         for (int i = 0; i < openProjects.length; i++) {
212             if (openProjects[i] == original) {
213                 opened = true;
214                 break;
215             }
216         }
217         return opened;
218     }
219     
220 // XXX following is copy-pasted from the Project APIs
221
//<editor-fold defaultstate="collapsed" desc="copy-pasted from Project API">
222
private static FileObject doCopy(final Project original,
223             final FileObject from, final FileObject toParent) throws IOException JavaDoc {
224         if (!VisibilityQuery.getDefault().isVisible(from)) {
225             //Do not copy invisible files/folders.
226
return null;
227         }
228         
229         if (!original.getProjectDirectory().equals(FileOwnerQuery.getOwner(from).getProjectDirectory())) {
230             return null;
231         }
232         
233         FileObject copy;
234         if (from.isFolder()) {
235             copy = toParent.createFolder(from.getNameExt());
236             FileObject[] kids = from.getChildren();
237             for (int i = 0; i < kids.length; i++) {
238                 doCopy(original, kids[i], copy);
239             }
240         } else {
241             assert from.isData();
242             copy = FileUtil.copyFile(from, toParent, from.getName(), from.getExt());
243         }
244         return copy;
245     }
246     
247     private static boolean doDelete(final Project original,
248             final FileObject toDelete) throws IOException JavaDoc {
249         if (!original.getProjectDirectory().equals(FileOwnerQuery.getOwner(toDelete).getProjectDirectory())) {
250             return false;
251         }
252         
253         if (toDelete.isFolder()) {
254             FileObject[] kids = toDelete.getChildren();
255             boolean delete = true;
256             
257             for (int i = 0; i < kids.length; i++) {
258                 delete &= doDelete(original, kids[i]);
259             }
260             
261             if (delete) {
262                 toDelete.delete();
263             }
264             
265             return delete;
266         } else {
267             assert toDelete.isData();
268             toDelete.delete();
269             return true;
270         }
271     }
272     
273     private static void close(final Project prj) {
274         Mutex.EVENT.readAccess(new Mutex.Action() {
275             public Object JavaDoc run() {
276                 LifecycleManager.getDefault().saveAll();
277                 
278                 Action JavaDoc closeAction = CommonProjectActions.closeProjectAction();
279                 closeAction = closeAction instanceof ContextAwareAction ? ((ContextAwareAction) closeAction).createContextAwareInstance(Lookups.fixed(new Object JavaDoc[] {prj})) : null;
280                 
281                 if (closeAction != null && closeAction.isEnabled()) {
282                     closeAction.actionPerformed(new ActionEvent JavaDoc(prj, -1, "")); // NOI18N
283
} else {
284                     //fallback:
285
OpenProjects.getDefault().close(new Project[] {prj});
286                 }
287                 
288                 return null;
289             }
290         });
291     }
292 //</editor-fold>
293

294 }
295
Popular Tags