![JAR search and dependency download from the Maven repository](/logo.png)
org.eclipse.jetty.start.Modules Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.start;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jetty.util.TopologicalSort;
/**
* Access for all modules declared, as well as what is enabled.
*/
public class Modules implements Iterable
{
private final List _modules = new ArrayList<>();
private final Map _names = new HashMap<>();
private final Map> _provided = new HashMap<>();
private final BaseHome _baseHome;
private final StartArgs _args;
public Modules(BaseHome basehome, StartArgs args)
{
this._baseHome = basehome;
this._args = args;
String java_version = System.getProperty("java.version");
if (java_version!=null)
{
args.setProperty("java.version",java_version,"",false);
}
}
public void dump()
{
List ordered = _modules.stream().map(m->{return m.getName();}).collect(Collectors.toList());
Collections.sort(ordered);
ordered.stream().map(n->{return get(n);}).forEach(module->
{
String status = "[ ]";
if (module.isTransitive())
{
status = "[t]";
}
else if (module.isEnabled())
{
status = "[x]";
}
System.out.printf("%n %s Module: %s%n",status,module.getName());
if (module.getProvides().size()>1)
{
System.out.printf(" Provides: %s%n",module.getProvides());
}
for (String description : module.getDescription())
{
System.out.printf(" : %s%n",description);
}
for (String parent : module.getDepends())
{
System.out.printf(" Depend: %s%n",parent);
}
for (String optional : module.getOptional())
{
System.out.printf(" Optional: %s%n",optional);
}
for (String lib : module.getLibs())
{
System.out.printf(" LIB: %s%n",lib);
}
for (String xml : module.getXmls())
{
System.out.printf(" XML: %s%n",xml);
}
for (String jvm : module.getJvmArgs())
{
System.out.printf(" JVM: %s%n",jvm);
}
if (module.isEnabled())
{
for (String selection : module.getEnableSources())
{
System.out.printf(" Enabled: %s%n",selection);
}
}
});
}
public void dumpSelected()
{
int i=0;
for (Module module:getSelected())
{
String name=module.getName();
String index=(i++)+")";
for (String s:module.getEnableSources())
{
System.out.printf(" %4s %-15s %s%n",index,name,s);
index="";
name="";
}
}
}
public void registerAll() throws IOException
{
for (Path path : _baseHome.getPaths("modules/*.mod"))
{
registerModule(path);
}
}
private Module registerModule(Path file)
{
if (!FS.canReadFile(file))
{
throw new IllegalStateException("Cannot read file: " + file);
}
String shortName = _baseHome.toShortForm(file);
try
{
StartLog.debug("Registering Module: %s",shortName);
Module module = new Module(_baseHome,file);
_modules.add(module);
_names.put(module.getName(),module);
module.getProvides().forEach(n->{
_provided.computeIfAbsent(n,k->new HashSet()).add(module);
});
return module;
}
catch (Error|RuntimeException t)
{
throw t;
}
catch (Throwable t)
{
throw new IllegalStateException("Unable to register module: " + shortName,t);
}
}
@Override
public String toString()
{
StringBuilder str = new StringBuilder();
str.append("Modules[");
str.append("count=").append(_modules.size());
str.append(",<");
final AtomicBoolean delim = new AtomicBoolean(false);
_modules.forEach(m->
{
if (delim.get())
str.append(',');
str.append(m.getName());
delim.set(true);
});
str.append(">");
str.append("]");
return str.toString();
}
public void sort()
{
TopologicalSort sort = new TopologicalSort<>();
for (Module module: _modules)
{
Consumer add = name ->
{
Module dependency = _names.get(name);
if (dependency!=null)
sort.addDependency(module,dependency);
};
module.getDepends().forEach(add);
module.getOptional().forEach(add);
}
sort.sort(_modules);
}
public List getSelected()
{
return _modules.stream().filter(m->{return m.isEnabled();}).collect(Collectors.toList());
}
public Set select(String name, String enabledFrom)
{
Module module = get(name);
if (module==null)
throw new UsageException(UsageException.ERR_UNKNOWN,"Unknown module='%s'",name);
Set enabled = new HashSet<>();
enable(enabled,module,enabledFrom,false);
return enabled;
}
private void enable(Set newlyEnabled, Module module, String enabledFrom, boolean transitive)
{
StartLog.debug("enable %s from %s transitive=%b",module,enabledFrom,transitive);
// Check that this is not already provided by another module!
for (String name:module.getProvides())
{
Set providers = _provided.get(name);
if (providers!=null)
{
providers.forEach(p->
{
if (p!=module && p.isEnabled())
{
// If the already enabled module is transitive and this enable is not
if (p.isTransitive() && !transitive)
{
p.clearTransitiveEnable();
if (p.hasDefaultConfig())
{
p.getDefaultConfig().forEach(a->
{
_args.removeProperty(a,p.getName());
});
}
}
else
throw new UsageException("Capability %s already enabled by %s for %s",name,p.getName(),module.getName());
}
});
}
}
// Enable the module
if (module.enable(enabledFrom,transitive))
{
StartLog.debug("enabled %s",module.getName());
newlyEnabled.add(module.getName());
// Expand module properties
module.expandProperties(_args.getProperties());
// Apply default configuration
if (module.hasDefaultConfig())
{
for(String line:module.getDefaultConfig())
_args.parse(line,module.getName(),false);
for (Module m:_modules)
m.expandProperties(_args.getProperties());
}
}
else if (module.isTransitive() && module.hasIniTemplate())
newlyEnabled.add(module.getName());
// Process module dependencies (always processed as may be dynamic)
for(String dependsOn:module.getDepends())
{
// Look for modules that provide that dependency
Set providers = _provided.get(dependsOn);
StartLog.debug("%s depends on %s provided by ",module,dependsOn,providers);
// If there are no known providers of the module
if ((providers==null||providers.isEmpty()))
{
// look for a dynamic module
if (dependsOn.contains("/"))
{
Path file = _baseHome.getPath("modules/" + dependsOn + ".mod");
registerModule(file).expandProperties(_args.getProperties());
sort();
providers = _provided.get(dependsOn);
if (providers==null || providers.isEmpty())
throw new UsageException("Module %s does not provide %s",_baseHome.toShortForm(file),dependsOn);
enable(newlyEnabled,providers.stream().findFirst().get(),"dynamic dependency of "+module.getName(),true);
continue;
}
throw new UsageException("No module found to provide %s for %s",dependsOn,module);
}
// If a provider is already enabled, then add a transitive enable
long enabled=providers.stream().filter(Module::isEnabled).count();
if (enabled>0)
providers.stream().filter(m->m.isEnabled()&&m!=module).forEach(m->enable(newlyEnabled,m,"transitive provider of "+dependsOn+" for "+module.getName(),true));
else
{
// Is there an obvious default?
Optional dftProvider = providers.stream().filter(m->m.getName().equals(dependsOn)).findFirst();
if (dftProvider.isPresent())
enable(newlyEnabled,dftProvider.get(),"default provider of "+dependsOn+" for "+module.getName(),true);
else
throw new UsageException("Module %s requires %s from one of %s",module,dependsOn,providers);
}
}
}
public Module get(String name)
{
return _names.get(name);
}
@Override
public Iterator iterator()
{
return _modules.iterator();
}
public Stream stream()
{
return _modules.stream();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy