All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.autoupdate.services.FeatureUpdateElementImpl Maven / Gradle / Ivy

The newest version!
/*
 * 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.services;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.Module;
import org.netbeans.api.autoupdate.UpdateElement;
import org.netbeans.api.autoupdate.UpdateManager;
import org.netbeans.api.autoupdate.UpdateUnit;
import org.netbeans.api.autoupdate.UpdateUnitProvider;
import org.netbeans.modules.autoupdate.updateprovider.ArtificialFeaturesProvider;
import org.netbeans.modules.autoupdate.updateprovider.FeatureItem;
import org.netbeans.modules.autoupdate.updateprovider.InstallInfo;
import org.openide.modules.Dependency;
import org.openide.modules.ModuleInfo;
import org.openide.modules.SpecificationVersion;
import org.openide.util.NbBundle;

/**
 *
 * @author Jiri Rechtacek
 */
public class FeatureUpdateElementImpl extends UpdateElementImpl {
    private String codeName;
    private String displayName;
    private SpecificationVersion specVersion;
    private String description;
    private String homepage;
    private String category;
    private InstallInfo installInfo;
    private static final Logger LOG = Logger.getLogger (FeatureUpdateElementImpl.class.getName ());
    
    /**
     * Missing (necessary) dependencies, module codenames
     */
    private Set missingElements;
    private Set moduleElementsImpl;
    private Set featureElementsImpl;
    private UpdateManager.TYPE type;
    
    public FeatureUpdateElementImpl (FeatureItem item, String providerName,
            Set moduleElementsImpl,
            Set featureElementsImpl,
            Set missing, 
            UpdateManager.TYPE type) {
        super (item, providerName);
        this.type = type;
        this.moduleElementsImpl = moduleElementsImpl;
        this.featureElementsImpl = featureElementsImpl;
        codeName = item.getCodeName ();
        String itemSpec = item.getSpecificationVersion ();
        if (itemSpec == null) {
            LOG.log (Level.INFO, codeName + " has no specificationVersion.");
        } else {
            specVersion = new SpecificationVersion (itemSpec);
        }
        installInfo = new InstallInfo (item);
        displayName = item.getDisplayName ();
        description = item.getDescription ();
        category = item.getCategory ();
        if (category == null) {
            category = NbBundle.getMessage (UpdateElementImpl.class, "UpdateElementImpl_Feature_CategoryName");
        }
        missingElements = missing == null ? Collections.emptySet() : missing;
    }
    
    @Override
    public String getCodeName () {
        return codeName;
    }
    
    @Override
    public String getDisplayName () {
        return displayName;
    }
    
    @Override
    public SpecificationVersion getSpecificationVersion () {
        if (specVersion == null) {
            specVersion = new SpecificationVersion (ArtificialFeaturesProvider.createVersion (getModuleInfos ()));
        }
        return specVersion;
    }
    
    @Override
    public String getDescription () {
        return description;
    }
    
    @Override
    public String getNotification() {
        return null;
    }
    
    @Override
    public String getAuthor () {
        String res = "";
        Set authors = new HashSet ();
        for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) {
            if (impl.getAuthor () != null) {
                if (authors.add (impl.getAuthor ())) {
                    res += res.length () == 0 ? impl.getAuthor () : ", " + impl.getAuthor (); // NOI18N
                }
            }
        }
        return res;
    }
    
    @Override
    public String getHomepage () {
        return homepage;
    }
    
    @Override
    public int getDownloadSize () {
        int res = 0;
        for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) {
            if (! impl.getUpdateUnit ().getAvailableUpdates ().isEmpty ()) {
                res += impl.getUpdateUnit ().getAvailableUpdates ().get (0).getDownloadSize ();
            }
        }
        return res;
    }
    
    @Override
    public String getSource () {
        String res = "";
        Set sources = new HashSet ();
        for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) {
            if (sources.add (impl.getSource ())) {
                res += res.length () == 0 ? impl.getSource () : ", " + impl.getSource (); // NOI18N
            }
        }
        return res;
    }
    
    @Override
    public String getCategory () {
        if (isAutoload () || isFixed ()) {
            category = UpdateUnitFactory.LIBRARIES_CATEGORY;
        } else if (isEager ()) {
            category = UpdateUnitFactory.BRIDGES_CATEGORY;
        } else if (category == null || category.length () == 0) {
            category = UpdateUnitFactory.UNSORTED_CATEGORY;
        }
        return category;
    }
    
    @Override
    public String getDate () {
        String res = null;
        Date date = null;
        for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) {
            String sd = impl.getDate ();
            if (sd != null) {
                try {
                    Date d = Utilities.parseDate(sd);
                    date = date == null ? d : new Date (Math.max (date.getTime (), d.getTime ()));
                } catch (ParseException pe) {
                    assert false : pe + " cannot happened.";
                }
            }
        }
        if (date != null) {
            res = Utilities.formatDate(date);
        }
        return res;
    }
    
    @Override
    public String getLicenseId() {
        String res = "";
        Set ids = new HashSet();
        for (ModuleUpdateElementImpl impl : getContainedModuleElements()) {
            if (!impl.getUpdateUnit().getAvailableUpdates().isEmpty()) {
                String id = impl.getUpdateUnit().getAvailableUpdates().get(0).getLicenseId();
                if (ids.add(id)) {
                    res += res.length() == 0 ? id : "," + id; // NOI18N
                }
            }
        }
        return res;
    }
    
    @Override
    public String getLicence () {
        String res = "";
        Set licenses = new HashSet ();
        for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) {
            if (! impl.getUpdateUnit ().getAvailableUpdates ().isEmpty ()) {
                String lic = impl.getUpdateUnit ().getAvailableUpdates ().get (0).getLicence ();
                if (licenses.add (lic)) {
                    res += res.length () == 0 ? lic : "
" + lic; // NOI18N } } } return res; } @Override public InstallInfo getInstallInfo () { return installInfo; } @Override public List getModuleInfos () { return getModuleInfos(false); } @Override public List getModuleInfos(boolean recursive) { List infos = new ArrayList(); for (ModuleUpdateElementImpl impl : getContainedModuleElements()) { if (! infos.contains(impl.getModuleInfo())) { infos.add(impl.getModuleInfo()); } } if (recursive) { for (FeatureUpdateElementImpl featureImpl : getDependingFeatures()) { for (ModuleUpdateElementImpl modImpl : featureImpl.getContainedModuleElements()) { if (! infos.contains(modImpl.getModuleInfo())) { infos.add(modImpl.getModuleInfo()); } } } } return infos; } public Set getContainedModuleElements () { assert moduleElementsImpl != null : "FeatureUpdateElementImpl contains modules " + moduleElementsImpl; return moduleElementsImpl; } public Set getDependingFeatures() { assert featureElementsImpl != null : "FeatureUpdateElementImpl contains features " + featureElementsImpl; return featureElementsImpl; } @Override public UpdateManager.TYPE getType () { return type; } @Override public boolean isEnabled () { boolean res = true; for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) { res &= impl.isEnabled (); } for (FeatureUpdateElementImpl featureImpl : getDependingFeatures()) { res &= featureImpl.isEnabled(); } return res; } @Override public boolean isAutoload () { boolean res = true; for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) { res &= impl.isAutoload (); } for (FeatureUpdateElementImpl featureImpl : getDependingFeatures()) { res &= featureImpl.isAutoload(); } return res; } @Override public boolean isEager () { boolean res = true; for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) { res &= impl.isEager (); } for (FeatureUpdateElementImpl featureImpl : getDependingFeatures()) { res &= featureImpl.isEager(); } return res; } @Override public boolean isFixed () { boolean res = true; for (ModuleUpdateElementImpl impl : getContainedModuleElements ()) { res &= impl.isFixed (); } for (FeatureUpdateElementImpl featureImpl : getDependingFeatures()) { res &= featureImpl.isFixed(); } return res; } @Override public boolean isPreferredUpdate() { boolean res = true; for (ModuleUpdateElementImpl impl : getContainedModuleElements()) { res &= impl.isPreferredUpdate(); } for (FeatureUpdateElementImpl featureImpl : getDependingFeatures()) { res &= featureImpl.isPreferredUpdate(); } return res; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final FeatureUpdateElementImpl other = (FeatureUpdateElementImpl) obj; if (this.specVersion != other.specVersion && (this.specVersion == null || !this.specVersion.equals(other.specVersion))) { return false; } if (this.codeName != other.codeName && (this.codeName == null || !this.codeName.equals(other.codeName))) { return false; } return true; } @Override public int hashCode() { int hash = 5; hash = 61 * hash + (this.codeName != null ? this.codeName.hashCode() : 0); hash = 61 * hash + (this.specVersion != null ? this.specVersion.hashCode() : 0); return hash; } @Override public String toString() { return "FeatureUpdateElementImpl[" + this.codeName + "/" + this.specVersion + "]"; } /** * Returns unknown codenames * @return unknown codenames or empty collection */ public Set getMissingElements() { return missingElements; } public static class Agent extends FeatureUpdateElementImpl { private Set moduleElementsImpl; private Set featureElementsImpl; private Set missingImpl = Collections.emptySet(); private FeatureItem featureItem; public Agent (FeatureItem item, String providerName, UpdateManager.TYPE type) { super (item, providerName, null, null, null, type); this.featureItem = item; } @Override public Set getContainedModuleElements () { initializeAgent(); assert moduleElementsImpl != null : "FeatureUpdateElementImpl contains modules " + moduleElementsImpl; return moduleElementsImpl; } @Override public Set getDependingFeatures() { initializeAgent(); assert featureElementsImpl != null : "FeatureUpdateElementImpl depends on features " + featureElementsImpl; return featureElementsImpl; } @Override public Set getMissingElements() { initializeAgent(); return missingImpl; } private void initializeAgent() { synchronized(this) { if (featureElementsImpl == null || moduleElementsImpl == null) { Set depFeatures = new HashSet(); moduleElementsImpl = processContainedModules (featureItem.getModuleCodeNames (), null, depFeatures); featureElementsImpl = depFeatures; } } } private Set processContainedModules ( Set dependenciesToModulesOrFeatures, UpdateUnitProvider provider, Set depFeatures ) { Set res = new HashSet (); assert dependenciesToModulesOrFeatures != null : "Invalid Feature " + this + " with null modules."; if (dependenciesToModulesOrFeatures == null) { dependenciesToModulesOrFeatures = new HashSet(); } else { dependenciesToModulesOrFeatures = new HashSet(dependenciesToModulesOrFeatures); } Set deps = new HashSet (); for (String depSpec : dependenciesToModulesOrFeatures) { deps.addAll (Dependency.create (Dependency.TYPE_MODULE, depSpec)); } List moduleUnits = provider == null ? UpdateManager.getDefault ().getUpdateUnits (UpdateManager.TYPE.MODULE) : provider.getUpdateUnits (UpdateManager.TYPE.MODULE); for (UpdateUnit unit : moduleUnits) { for (Iterator it = deps.iterator(); it.hasNext();) { Dependency dep = it.next(); assert Dependency.TYPE_MODULE == dep.getType () : "Only Dependency.TYPE_MODULE supported, but " + dep; String name = dep.getName (); // trim release impl. if (name.indexOf ('/') != -1) { int to = name.indexOf ('/'); name = name.substring (0, to); } if (unit.getCodeName ().equals (name)) { UpdateElement el = getMatchedUpdateElement (unit, dep); if (el != null) { assert Trampoline.API.impl (el) instanceof ModuleUpdateElementImpl : "Impl of " + el + " is instanceof ModuleUpdateElementImpl."; ModuleUpdateElementImpl impl = (ModuleUpdateElementImpl) Trampoline.API.impl (el); res.add (impl); dependenciesToModulesOrFeatures.remove(name); it.remove(); } else { LOG.log (Level.INFO, getUpdateUnit () + " requires a module " + name + " what is not present."); } } } } if (!dependenciesToModulesOrFeatures.isEmpty()) { List features = provider == null ? UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.FEATURE) : provider.getUpdateUnits(UpdateManager.TYPE.FEATURE); for (UpdateUnit feat : features) { for (Iterator it = deps.iterator(); it.hasNext();) { Dependency dep = it.next(); final String name = dep.getName(); if (name.equals(feat.getCodeName())) { UpdateElement el = getMatchedUpdateElement(feat, dep); if (el != null) { assert Trampoline.API.impl(el) instanceof FeatureUpdateElementImpl : "Impl of " + el + " is instanceof FeatureUpdateElementImpl."; FeatureUpdateElementImpl impl = (FeatureUpdateElementImpl) Trampoline.API.impl(el); if (depFeatures.add(impl)) { //res.addAll(impl.getContainedModuleElements()); } dependenciesToModulesOrFeatures.remove(name); it.remove(); } else { LOG.log(Level.INFO, getUpdateUnit() + " requires a feature " + name + " what is not present."); } } } } } for (Iterator it = dependenciesToModulesOrFeatures.iterator(); it.hasNext();) { String depSpec = it.next(); for (Dependency dep : Dependency.create (Dependency.TYPE_MODULE, depSpec)) { String cnb = dep.getName (); // trim release impl. if (cnb.indexOf ('/') != -1) { int to = cnb.indexOf ('/'); cnb = cnb.substring (0, to); } Module m = Utilities.toModule(cnb, null); if (m != null && ! m.getProblems().isEmpty()) { it.remove(); break; } } } if (!dependenciesToModulesOrFeatures.isEmpty()) { missingImpl = new HashSet<>(dependenciesToModulesOrFeatures); LOG.log(Level.INFO, this.featureItem + " depends on non-existing " + dependenciesToModulesOrFeatures); } return res; } private static UpdateElement getMatchedUpdateElement (UpdateUnit unit, Dependency dep) { // find installed if (match (unit.getInstalled (), dep)) { return unit.getInstalled (); } else { // find available updates if (! unit.getAvailableUpdates ().isEmpty ()) { if (match (unit.getAvailableUpdates ().get (0), dep)) { return unit.getAvailableUpdates ().get (0); } } } return null; } private static boolean match (UpdateElement el, Dependency dep) { if (el == null) { return false; } UpdateElementImpl impl = Trampoline.API.impl(el); if (impl instanceof FeatureUpdateElementImpl) { if (dep.getVersion() == null) { return true; } SpecificationVersion v = new SpecificationVersion(dep.getVersion()); return v.compareTo(impl.getSpecificationVersion()) >= 0; } return DependencyChecker.checkDependencyModuleAllowEqual (dep, Utilities.takeModuleInfo (el)); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy