1 19 20 package org.netbeans.modules.apisupport.project.ui; 21 22 import java.awt.event.ActionEvent ; 23 import java.io.File ; 24 import java.io.IOException ; 25 import java.util.ArrayList ; 26 import java.util.Collections ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Set ; 33 import javax.swing.Action ; 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 67 public final class SuiteOperations implements DeleteOperationImplementation, 68 MoveOperationImplementation { 69 70 private static final Map <String ,Set <NbModuleProject>> TEMPORARY_CACHE = new HashMap (); 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 { 81 FileObject buildXML = projectDir.getFileObject(GeneratedFilesHelper.BUILD_XML_PATH); 82 ActionUtils.runTarget(buildXML, new String [] { ActionProvider.COMMAND_CLEAN }, null).waitFinished(); 83 84 SubprojectProvider spp = (SubprojectProvider) suite.getLookup().lookup(SubprojectProvider.class); 86 for (Iterator 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 { 93 suite.getHelper().notifyDeleted(); 94 } 95 96 public void notifyMoving() throws IOException { 97 Set <NbModuleProject> subprojects = SuiteUtils.getSubProjects(suite); 98 if (!subprojects.isEmpty()) { 99 TEMPORARY_CACHE.put(ProjectUtils.getInformation(suite).getName(), subprojects); 102 } 103 notifyDeleting(); 107 } 108 109 public void notifyMoved(Project original, File originalPath, String nueName) throws IOException { 110 if (original == null) { suite.getHelper().notifyDeleted(); 112 } else { String name = ProjectUtils.getInformation(suite).getName(); 114 Set <Project> subprojects = (Set ) TEMPORARY_CACHE.remove(name); 115 if (subprojects != null) { 116 Set toOpen = new HashSet (); 117 for (Iterator 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( 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 <FileObject> getMetadataFiles() { 149 List <FileObject> files = new ArrayList (); 150 addFile(GeneratedFilesHelper.BUILD_XML_PATH, files); 151 addFile("nbproject", files); addFile(".cvsignore", files); return files; 154 } 155 156 public List <FileObject> getDataFiles() { 157 List <FileObject> files = new ArrayList (); 158 addFile(suite.getEvaluator().getProperty(BrandingSupport.BRANDING_DIR_PROPERTY), files); 159 return files; 160 } 161 162 private void addFile(String fileName, List <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 nueName) throws IOException { 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 run() throws IOException { 176 if (branding.isBrandingEnabled()) { branding.setTitle(nueName); 178 sp.storeProperties(); 179 } else { 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 ) e.getException(); 190 } 191 } 192 193 194 static Project moveModule(final NbModuleProject original, final FileObject targetParent) throws IOException , IllegalArgumentException { 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 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 private static FileObject doCopy(final Project original, 223 final FileObject from, final FileObject toParent) throws IOException { 224 if (!VisibilityQuery.getDefault().isVisible(from)) { 225 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 { 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 run() { 276 LifecycleManager.getDefault().saveAll(); 277 278 Action closeAction = CommonProjectActions.closeProjectAction(); 279 closeAction = closeAction instanceof ContextAwareAction ? ((ContextAwareAction) closeAction).createContextAwareInstance(Lookups.fixed(new Object [] {prj})) : null; 280 281 if (closeAction != null && closeAction.isEnabled()) { 282 closeAction.actionPerformed(new ActionEvent (prj, -1, "")); } else { 284 OpenProjects.getDefault().close(new Project[] {prj}); 286 } 287 288 return null; 289 } 290 }); 291 } 292 294 } 295 | Popular Tags |