blob: e7c5f7d43b1719e63d375ae313fa9578ef566fcb [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.autoupdate.pluginimporter;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.autoupdate.UpdateUnitProvider;
import org.netbeans.api.autoupdate.UpdateUnitProvider.CATEGORY;
import org.netbeans.spi.autoupdate.UpdateItem;
import org.netbeans.spi.autoupdate.UpdateLicense;
import org.netbeans.spi.autoupdate.UpdateProvider;
import org.openide.util.NbBundle;
import org.openide.xml.EntityCatalog;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
*
* @author Jiri Rechtacek
*/
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.autoupdate.UpdateProvider.class)
public class ClusterUpdateProvider implements UpdateProvider {
private static File cluster = null;
private static Logger LOG = Logger.getLogger (ClusterUpdateProvider.class.getName ());
private static final String ELEMENT_MODULE = "module"; // NOI18N
public ClusterUpdateProvider () {}
public static void attachCluster (File newCluster) {
if (newCluster == null) {
throw new IllegalArgumentException ("Cluster cannot be null!"); // NOI18N
}
cluster = newCluster;
}
public String getName () {
return Installer.CODE_NAME;
}
public String getDisplayName () {
if (cluster == null) { // netbeans.full.hack etc.
return NbBundle.getMessage(ClusterUpdateProvider.class, "ClusterUpdateProvider_DisplayName_disabled");
}
return NbBundle.getMessage (ClusterUpdateProvider.class, "ClusterUpdateProvider_DisplayName", cluster); // NOI18N
}
public String getDescription () {
return NbBundle.getMessage (ClusterUpdateProvider.class, "ClusterUpdateProvider_Description"); // NOI18N
}
public CATEGORY getCategory () {
return UpdateUnitProvider.CATEGORY.STANDARD;
}
public Map<String, UpdateItem> getUpdateItems () throws IOException {
Map<String, UpdateItem> res = new HashMap<String, UpdateItem> ();
for (File cf: readModules (cluster)) {
String cnb = (cf.getName ().substring (0, cf.getName ().length () - ".xml".length ())).replaceAll ("-", "."); // NOI18N
Map<String, String> attr = new HashMap<String, String> (7);
readConfigFile (cf, attr);
String jarName = attr.get ("jar");
if(jarName == null) {
LOG.info ("Can`t get jar file name for " + cnb + ", skip checking.");
continue;
}
File jarFile = new File (cluster, jarName); // NOI18N
if (! jarFile.exists ()) {
LOG.info ("Jar file " + jarFile + " doesn't exists. Skip checking " + cnb);
continue;
}
File updateTrackingFile = new File(cluster, "update_tracking" + File.separator + cf.getName());
if (! updateTrackingFile.exists ()) {
LOG.info ("Update tracking file " + updateTrackingFile + " doesn't exists. Skip checking " + cnb);
continue;
}
Manifest mf = new JarFile (jarFile).getManifest ();
UpdateItem item = UpdateItem.createModule (
cnb,
attr.get ("specversion"), // NOI18N
null,
cluster.getName (), // XXX: to identify such items later
"0", // NOI18N
"",
"",
"",
mf,
Boolean.valueOf (attr.get ("eager")), // NOI18N
Boolean.valueOf (attr.get ("autoload")), // NOI18N
null,
null,
"",
UpdateLicense.createUpdateLicense ("unknown-license", "none")); // NOI18N
res.put (cnb + '_' + attr.get ("specversion"), item); // NOI18N
}
return res;
}
public boolean refresh (boolean force) throws IOException {
return true;
}
private static Collection<File> readModules (File cluster) {
if (cluster == null || ! cluster.exists ()) {
return Collections.emptySet ();
}
Collection<File> res = new HashSet<File> ();
File config = new File (new File (cluster, "config"), "Modules"); // NOI18N
if (config.listFiles () == null) {
return Collections.emptySet ();
}
for (File cf : config.listFiles ()) {
if(cf.getName ().endsWith(".xml_hidden")) {
//158204
continue;
}
if (cf.getName ().endsWith (".xml")) { // NOI18N
if(cf.length() > 0) {
res.add (cf);
} else {
LOG.log(Level.INFO, "Found zero-sized xml file in config/Modules, ignoring: " + cf);
}
} else {
LOG.log(Level.INFO, "Found non-xml file in config/Modules, ignoring: " + cf);
}
}
return res;
}
private static void readConfigFile (File cf, Map<String, String> attr) {
Document document = null;
InputStream is = null;
try {
is = new BufferedInputStream (new FileInputStream (cf));
InputSource xmlInputSource = new InputSource (is);
document = XMLUtil.parse (xmlInputSource, false, false, null, EntityCatalog.getDefault ());
} catch (SAXException saxe) {
LOG.log(Level.INFO, "Error while reading " + cf);
LOG.log(Level.INFO, saxe.getLocalizedMessage (), saxe);
return;
} catch (IOException ioe) {
LOG.log(Level.INFO, "Error while reading " + cf);
LOG.log(Level.WARNING, ioe.getLocalizedMessage (), ioe);
} finally {
if (is != null) {
try {
is.close ();
} catch (IOException e){
//ignore
}
}
}
assert document.getDocumentElement () != null : "File " + cf + " must contain document element.";
Element element = document.getDocumentElement ();
assert ELEMENT_MODULE.equals (element.getTagName ()) : "The root element is: " + ELEMENT_MODULE + " but was: " + element.getTagName ();
NodeList children = element.getChildNodes ();
for (int i = 0; i < children.getLength (); i++) {
Node n = children.item (i);
if (Node.ELEMENT_NODE != n.getNodeType()) {
continue;
}
Element e = (Element) n;
String name = e.getAttributes ().getNamedItem ("name").getNodeValue (); // NOI18N
String value = e.getChildNodes ().item (0).getNodeValue ();
attr.put (name, value);
}
}
}