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