|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2002 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.autoupdate; import java.util.*; import org.openide.DialogDisplayer; import org.openide.util.NbBundle; import org.openide.NotifyDescriptor; import org.openide.modules.ModuleInfo; import org.openide.modules.Dependency; import org.openide.modules.SpecificationVersion; /** Support class for checking dependencies between modules * * @author phrebejk */ class DependencyChecker extends Object { /** DependencyChecker is a singleton */ DependencyChecker() { } /** Gets collection of modules which have to be added to download list * if we have to add the toAddModule. */ Collection modulesToAdd( ModuleUpdate toAdd, Enumeration selected, List group, StringBuffer dontAddModuleName ) { Collection result = new ArrayList(); checkDependencies( toAdd.getRemoteModule(), result, selected, group, dontAddModuleName, toAdd.getLocalModule() != null ); return result; } /** Gets collection of modules which we have to remove from download list * if we have to remove the toRemove module. */ Collection modulesToRemove( ModuleUpdate toRemove, ModuleUpdate toReplace ) { Collection result = new ArrayList(); checkReverseDependencies( toRemove.getRemoteModule(), result, toReplace ); return result; } /** Builds Collection with modules which should be added * into download list to satisfy module dependencies. */ private boolean checkDependencies( ModuleInfo md, Collection result, Enumeration selected, List group, StringBuffer dontAddModuleName, boolean isUpgrade ) { // Get all module dependencies Set depsS = md.getDependencies(); Dependency[] deps = (Dependency[])depsS.toArray(new Dependency[depsS.size()]); // Array values say if the dependency is satisfied or not boolean[] satisfied = new boolean [ deps.length ]; // All installed modules ModuleInfo[] installedModules = Updates.getInstalledModules(); ModuleInfo[] installedPatches = Updates.getInstalledPatches(); // For all dependencies for ( int j = 0; j < deps.length; j++ ) { String message = null; // The module depends on other module if (deps[j].getType() == Dependency.TYPE_MODULE || deps[j].getType() == Dependency.TYPE_REQUIRES) { boolean ok = false; // Try to figure out if the dependency is satisfied by installed modules for (int i = 0; i < installedModules.length; i++) { ok = checkModuleDependency ( deps[j], installedModules[i] ); if ( ok ) break; } if ( !ok ) { // Try to figure out if the dependency is satisfied by installed patches for (int i = 0; i < installedPatches.length; i++) { ok = checkModuleDependency ( deps[j], installedPatches[i] ); if ( ok ) break; } } // Dependency was not satisfied by other module let's try modules // available for download if ( !ok && selected != null ) { while ( selected.hasMoreElements() ) { ModuleUpdate mu = (ModuleUpdate)selected.nextElement(); ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); if ( ok ) { if ( !result.contains( mu ) ) { result.add( mu ); } break; } } } if ( !ok && group != null ) { Iterator it = group.iterator(); while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); if ( ok ) { if ( !result.contains( mu ) ) { result.add( mu ); } break; } } } if ( !ok ) { Iterator it = Wizard.getAllModules().iterator(); while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); if ( ok ) { if ( !result.contains( mu ) ) { result.add( mu ); } break; } } } if ( !ok ) satisfied[j] = false; else satisfied[j] = true; } // Module depends on specific version of IDE else if ( deps[j].getType() == Dependency.TYPE_IDE ) { // Try to figure out if the dependency is satisfied by installed ide if ( checkIdeDependency ( deps[j], IdeDescription.getIdeDescription() ) ) { satisfied[j] = true; } else { // Try to find suitable IDE between the modules Iterator it = Wizard.getAllModules().iterator(); boolean ok = false; while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); ok = checkModuleDependency ( deps[j], mu.getRemoteModule() ); if ( ok ) { if ( !result.contains( mu ) ) { result.add( mu ); } break; } } satisfied[j] = ok; } } else // XXX what about Java/VM dependencies?! satisfied[j] = true; } StringBuffer sb = new StringBuffer( 280 ); sb.append( getBundle( "MSG_NotSatisfied" ) + "MODULE :" + md.getCodeName() ); int notSatisfied = 0; // For all dependencies for ( int j = 0; j < deps.length; j++ ) { if ( !satisfied[j] ) { sb.append( deps[j] ); notSatisfied++; } } StringBuffer sbbroken = null; if ( isUpgrade ) { // Checking, if upgrade of module doesn't break dependency of already // installed modules on it's certain implementation version List brokenlist = checkBrokenImplDependency( md, result ); if ( brokenlist.size() > 0 ) { sbbroken = new StringBuffer( 280 ); sbbroken.append( "MODULE :" + md.getCodeName() ); // NOI18N sbbroken.append( getBundle( "MSG_BadsList" ) ); Iterator it = brokenlist.iterator(); while ( it.hasNext() ) sbbroken.append( "\n" + ((ModuleInfo) it.next()).getCodeName() ); // NOI18N sbbroken.append( getBundle( "MSG_IncludeBadsAnyway" ) ); } } if ( notSatisfied == 0 && sbbroken == null ) return true; if ( notSatisfied > 0 ) { sb.append( getBundle( "MSG_IncludeAnyway" ) ); NotifyDescriptor.Confirmation nd = new NotifyDescriptor.Confirmation( sb.toString(), NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.ERROR_MESSAGE ); if ( ! DialogDisplayer.getDefault().notify( nd ).equals( NotifyDescriptor.YES_OPTION ) ) { dontAddModuleName.append( md.getDisplayName() ); return false; } } if ( sbbroken != null ) { NotifyDescriptor.Confirmation nd = new NotifyDescriptor.Confirmation( sbbroken.toString(), NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.ERROR_MESSAGE ); if ( ! DialogDisplayer.getDefault().notify( nd ).equals( NotifyDescriptor.YES_OPTION ) ) dontAddModuleName.append( md.getDisplayName() ); } return false; } /** Builds Collection with modules which should be removed * from download list to satisfy module dependencies. */ boolean checkReverseDependencies( ModuleInfo module, Collection result, ModuleUpdate toReplace ) { //ArrayList dependentModules = new ArrayList(); ModuleInfo[] installedModules = Updates.getInstalledModules(); ModuleInfo[] installedPatches = Updates.getInstalledPatches(); // All listed modules Iterator it = Wizard.getAllModules().iterator(); while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); //if ( !info.update() ) We have to check all modules // continue; ModuleInfo md = mu.getRemoteModule(); Set depsS = md.getDependencies(); Dependency[] deps = (Dependency[])depsS.toArray(new Dependency[depsS.size()]); // All dependencies of module boolean moduleOk = true; for ( int j = 0; j < deps.length; j++ ) { if ( (deps[j].getType() == Dependency.TYPE_MODULE && (deps[j].getName() + "/").startsWith( module.getCodeNameBase() + "/" )) || // NOI18N (deps[j].getType() == Dependency.TYPE_REQUIRES && Arrays.asList(module.getProvides()).contains(deps[j].getName())) ) { boolean ok = false; // Check if not satisfied by installed modules for (int k = 0; k < installedModules.length; k++) { ok = checkModuleDependency ( deps[j], installedModules[k] ); if ( ok ) break; } // Check if not satisfied by replacing module if ( !ok && toReplace != null ) ok = checkModuleDependency ( deps[j], toReplace.getRemoteModule() ); // Check if it is not stisfied by installed patches if ( !ok ) for (int k = 0; k < installedPatches.length; k++) { ok = checkModuleDependency ( deps[j], installedPatches[k] ); if ( ok ) break; } // The module has unsatisfied dependency we have to remove it if ( !ok ) { moduleOk = false; break; } } else if ( deps[j].getType() == Dependency.TYPE_IDE && // XXX how can this be true?! deps[j].getName().equals( module.getCodeName() ) ) { //Check if not satisfied by installed IDE if ( !checkModuleDependency ( deps[j], IdeDescription.getIdeDescription() ) ) { moduleOk = false; break; } } } if ( !moduleOk ) { if ( ! result.contains( mu ) ) { result.add( mu ); //checkReverseDependencies( mu.getRemoteModule(), result ); } } } return result.size() == 0; } /** Tests if the dependency on module is satisfied by the otherModule */ static boolean checkModuleDependency ( Dependency dep, ModuleInfo otherModule ) { if (dep.getType() == Dependency.TYPE_REQUIRES) { return Arrays.asList(otherModule.getProvides()).contains(dep.getName()); } boolean satisfied = false; String depName = dep.getName(); if ( depName.equals (otherModule.getCodeName ())) { if ( dep.getComparison() == Dependency.COMPARE_ANY) { return true; } else if (dep.getComparison() == Dependency.COMPARE_SPEC) { if (otherModule.getSpecificationVersion() == null) return false; else if (new SpecificationVersion(dep.getVersion()).compareTo(otherModule.getSpecificationVersion()) > 0) return false; else return true; } else { // COMPARE_IMPL if (otherModule.getImplementationVersion () == null) return false; else if (! otherModule.getImplementationVersion ().equals (dep.getVersion())) return false; else return true; } } int dash = depName.indexOf('-'); // NOI18N if (dash != -1) { // Ranged major release version, cf. #19714. int slash = depName.indexOf('/'); // NOI18N String cnb = depName.substring(0, slash); int relMin = Integer.parseInt(depName.substring(slash + 1, dash)); int relMax = Integer.parseInt(depName.substring(dash + 1)); if (cnb.equals(otherModule.getCodeNameBase()) && relMin <= otherModule.getCodeNameRelease() && relMax >= otherModule.getCodeNameRelease()) { if (dep.getComparison() == Dependency.COMPARE_ANY) { return true; } else { // COMPARE_SPEC; COMPARE_IMPL not allowed here if (otherModule.getCodeNameRelease() > relMin) { // Great, skip the spec version. return true; } else { // As usual. if (otherModule.getSpecificationVersion() == null) return false; else if (new SpecificationVersion(dep.getVersion()).compareTo(otherModule.getSpecificationVersion()) > 0) return false; else return true; } } } } return false; } /** Tests dependency on the IDE */ boolean checkIdeDependency( Dependency dep, ModuleInfo ide ) { String IDEName = ide.getCodeName(); SpecificationVersion IDESpecVersion = ide.getSpecificationVersion(); String IDEImplVersion = ide.getImplementationVersion(); // Not equal names if ( !IDEName.equals ( dep.getName() ) ) return false; //return ModuleDescription.getStringFormatted ("MSG_IDE_Name", name, IDEName); // NOI18N if ( dep.getComparison() == Dependency.COMPARE_SPEC ) { return new SpecificationVersion(dep.getVersion()).compareTo(IDESpecVersion) <= 0; // ? null : ModuleDescription.getStringFormatted ("MSG_IDE_Spec", version, IDESpecVersion); // NOI18N } else if ( dep.getComparison() == Dependency.COMPARE_IMPL ) { return dep.getVersion().equals (IDEImplVersion); // ? null : ModuleDescription.getStringFormatted ("MSG_IDE_Impl", version, IDEImplVersion); // NOI18N } else { // COMPARE_ANY throw new IllegalStateException("Cannot have COMPARE_ANY on IDE dependency"); // NOI18N } } private List checkBrokenImplDependency( ModuleInfo md, Collection result ) { ModuleInfo[] installedModules = Updates.getInstalledModules(); List brokenlist = new ArrayList(); Dependency dep, depR; for (int i = 0; i < installedModules.length; i++) { Iterator deps = installedModules[i].getDependencies().iterator(); while ( deps.hasNext() ) { dep = (Dependency) deps.next(); if ( dep.getName().equals (md.getCodeName ()) && dep.getComparison() == Dependency.COMPARE_IMPL ) { if ( ! dep.getVersion().equals( md.getImplementationVersion() ) ) { // Dependency ids broken, try to find if there is new version // of module with proper implementation version Iterator it = Wizard.getAllModules().iterator(); boolean found = false; while ( it.hasNext() ) { ModuleUpdate mu = (ModuleUpdate)it.next(); if ( mu.getRemoteModule().getCodeName().equals( installedModules[i].getCodeName() ) && mu.getRemoteModule().getSpecificationVersion().compareTo( installedModules[i].getSpecificationVersion() ) > 0 ) { boolean maybeOK = true; Iterator depsR = mu.getRemoteModule().getDependencies().iterator(); while ( depsR.hasNext() ) { depR = (Dependency) depsR.next(); if ( depR.getName().equals (md.getCodeName ()) && depR.getComparison() == Dependency.COMPARE_IMPL && !depR.getVersion().equals( md.getImplementationVersion() ) ) { maybeOK = false; break; } } if ( maybeOK ) { if ( !result.contains( mu ) ) { result.add( mu ); } found = true; break; } } } if ( !found ) { brokenlist.add( installedModules[i] ); } break; } break; } } } return brokenlist; } private String getBundle( String key ) { return NbBundle.getMessage( DependencyChecker.class, key ); } static Comparator getModuleDependencyComparator() { return new ModuleDependencyComparator(); } static class ModuleDependencyComparator implements Comparator { public int compare(Object obj, Object obj1) { if ( ! ( ( obj instanceof ModuleUpdate ) && ( obj1 instanceof ModuleUpdate ) ) ) return 0; ModuleInfo modA = ((ModuleUpdate)obj).getRemoteModule(); ModuleInfo modB = ((ModuleUpdate)obj1).getRemoteModule(); if ( moduleDependsOnModule( modA, modB ) ) return 1; else if ( moduleDependsOnModule( modB, modA ) ) return -1; else return 0; } // returns true if modA depends on modB private boolean moduleDependsOnModule(ModuleInfo modA, ModuleInfo modB) { Set depsA = modA.getDependencies(); Iterator it = depsA.iterator(); while ( it.hasNext() ) { Dependency dep = (Dependency)(it.next()); if (dep.getType() == Dependency.TYPE_MODULE || dep.getType() == Dependency.TYPE_REQUIRES) { if ( checkModuleDependency ( dep, modB ) ) return true; } } return false; } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.