blob: 5b11e11ba9bba574c464019fa7e92fafdeaddde7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.j2ee.earproject;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import org.netbeans.api.project.Project;
import org.w3c.dom.Element;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
import org.openide.util.Mutex;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.libraries.LibraryManager;
import org.netbeans.modules.java.api.common.ant.UpdateImplementation;
import org.netbeans.spi.project.AuxiliaryConfiguration;
import org.netbeans.spi.project.support.ant.AntProjectHelper;
import org.netbeans.spi.project.support.ant.EditableProperties;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
*/
public class UpdateProjectImpl implements UpdateImplementation {
private static final boolean TRANSPARENT_UPDATE = Boolean.getBoolean("webproject.transparentUpdate"); //NOI18N
private static final String BUILD_NUMBER = System.getProperty("netbeans.buildnumber"); // NOI18N
private Boolean isCurrent;
private final AuxiliaryConfiguration cfg;
private boolean alreadyAskedInWriteAccess;
private final Project project;
private final AntProjectHelper helper;
private Element cachedElement;
private static final String TAG_FILE = "file"; //NOI18N
private static final String TAG_LIBRARY = "library"; //NOI18N
private static final String ATTR_FILES = "files"; //NOI18N
private static final String ATTR_DIRS = "dirs"; //NOI18N
UpdateProjectImpl (Project project, AntProjectHelper helper, AuxiliaryConfiguration cfg) {
assert project != null && helper != null && cfg != null;
this.project = project;
this.helper = helper;
this.cfg = cfg;
}
public boolean isCurrent() {
return ProjectManager.mutex().readAccess(new Mutex.Action<Boolean>() {
public Boolean run() {
synchronized (this) {
if (isCurrent == null) {
isCurrent = cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-earproject/1",true) == null //NOI18N
? Boolean.TRUE : Boolean.FALSE;
}
return isCurrent;
}
}
}).booleanValue();
}
public boolean canUpdate() {
if (TRANSPARENT_UPDATE) {
return true;
}
//Ask just once under a single write access
if (alreadyAskedInWriteAccess) {
return false;
}
else {
boolean canUpdate = showUpdateDialog();
if (!canUpdate) {
alreadyAskedInWriteAccess = true;
ProjectManager.mutex().postReadRequest(new Runnable() {
public void run() {
alreadyAskedInWriteAccess = false;
}
});
}
return canUpdate;
}
}
private boolean showUpdateDialog() {
JButton updateOption = new JButton (NbBundle.getMessage(UpdateProjectImpl.class, "CTL_UpdateOption"));
return DialogDisplayer.getDefault().notify(
new NotifyDescriptor (NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdate", BUILD_NUMBER),
NbBundle.getMessage(UpdateProjectImpl.class,"TXT_ProjectUpdateTitle"),
NotifyDescriptor.DEFAULT_OPTION,
NotifyDescriptor.WARNING_MESSAGE,
new Object[] {
updateOption,
NotifyDescriptor.CANCEL_OPTION
},
updateOption)) == updateOption;
}
public void saveUpdate(EditableProperties props) throws IOException {
helper.putPrimaryConfigurationData(getUpdatedSharedConfigurationData(),true);
cfg.removeConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-earproject/1",true); //NOI18N
ProjectManager.getDefault().saveProject (project);
synchronized(this) {
isCurrent = Boolean.TRUE;
}
}
public Element getUpdatedSharedConfigurationData() {
if (cachedElement == null) {
final String ns = EarProjectType.PROJECT_CONFIGURATION_NAMESPACE; //NOI18N
Element oldRoot = this.cfg.getConfigurationFragment("data","http://www.netbeans.org/ns/j2ee-earproject/1" ,true); //NOI18N
if(oldRoot != null) {
Document doc = oldRoot.getOwnerDocument();
Element newRoot = doc.createElementNS(EarProjectType.PROJECT_CONFIGURATION_NAMESPACE,"data"); //NOI18N
XMLUtil.copyDocument(oldRoot, newRoot, EarProjectType.PROJECT_CONFIGURATION_NAMESPACE);
//update <web-module-/additional/-libraries/> to <j2ee-module-/additional/-libraries/>
// NodeList contList = newRoot.getElementsByTagNameNS(ns, "web-module-libraries");
// contList.item(0).setNodeValue(ArchiveProjectProperties.TAG_WEB_MODULE_LIBRARIES);
// contList = newRoot.getElementsByTagNameNS(ns, "web-module-additional-libraries");
// contList.item(0).setNodeValue(ArchiveProjectProperties.TAG_WEB_MODULE__ADDITIONAL_LIBRARIES);
NodeList libList = newRoot.getElementsByTagNameNS(ns, TAG_LIBRARY);
for (int i = 0; i < libList.getLength(); i++) {
if (libList.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element library = (Element) libList.item(i);
Node webFile = library.getElementsByTagNameNS(ns, TAG_FILE).item(0);
//remove ${ and } from the beginning and end
String webFileText = XMLUtil.findText(webFile);
webFileText = webFileText.substring(2, webFileText.length() - 1);
if (webFileText.startsWith("libs.")) {
String libName = webFileText.substring(5, webFileText.indexOf(".classpath")); //NOI18N
@SuppressWarnings("unchecked")
List<URL> roots = LibraryManager.getDefault().getLibrary(libName).getContent("classpath"); //NOI18N
List<FileObject> files = new ArrayList<FileObject>();
List<FileObject> dirs = new ArrayList<FileObject>();
for (URL rootUrl : roots) {
FileObject root = org.openide.filesystems.URLMapper.findFileObject(rootUrl);
if ("jar".equals(rootUrl.getProtocol())) { //NOI18N
root = FileUtil.getArchiveFile(root);
}
if (root != null) {
if (root.isData()) {
files.add(root);
} else {
dirs.add(root);
}
}
}
if (files.size() > 0) {
library.setAttribute(ATTR_FILES, "" + files.size());
}
if (dirs.size() > 0) {
library.setAttribute(ATTR_DIRS, "" + dirs.size());
}
}
}
}
cachedElement = newRoot;
}
}
return cachedElement;
}
public EditableProperties getUpdatedProjectProperties() {
return helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
}
}