blob: a4eb217471f774e98db633747af761c85c17c560 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 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.List;
import org.eclipse.jetty.start.graph.Graph;
import org.eclipse.jetty.start.graph.GraphException;
import org.eclipse.jetty.start.graph.OnlyTransitivePredicate;
import org.eclipse.jetty.start.graph.Selection;
/**
* Access for all modules declared, as well as what is enabled.
*/
public class Modules extends Graph<Module>
{
private final BaseHome baseHome;
private final StartArgs args;
public Modules(BaseHome basehome, StartArgs args)
{
this.baseHome = basehome;
this.args = args;
this.setSelectionTerm("enable");
this.setNodeTerm("module");
String java_version = System.getProperty("java.version");
if (java_version!=null)
{
args.setProperty("java.version",java_version,"<internal>",false);
}
}
public void dump()
{
List<Module> ordered = new ArrayList<>();
ordered.addAll(getNodes());
Collections.sort(ordered,new Module.NameComparator());
List<Module> active = getSelected();
for (Module module : ordered)
{
boolean activated = active.contains(module);
boolean selected = module.isSelected();
boolean transitive = selected && module.matches(OnlyTransitivePredicate.INSTANCE);
String status = "[ ]";
if (transitive)
{
status = "[t]";
}
else if (selected)
{
status = "[x]";
}
System.out.printf("%n %s Module: %s%n",status,module.getName());
if (!module.getName().equals(module.getFilesystemRef()))
{
System.out.printf(" Ref: %s%n",module.getFilesystemRef());
}
for (String parent : module.getParentNames())
{
System.out.printf(" Depend: %s%n",parent);
}
for (String lib : module.getLibs())
{
System.out.printf(" LIB: %s%n",lib);
}
for (String xml : module.getXmls())
{
System.out.printf(" XML: %s%n",xml);
}
if (StartLog.isDebugEnabled())
{
System.out.printf(" depth: %d%n",module.getDepth());
}
if (activated)
{
for (Selection selection : module.getSelections())
{
System.out.printf(" Enabled: <via> %s%n",selection);
}
}
else
{
System.out.printf(" Enabled: <not enabled in this configuration>%n");
}
}
}
@Override
public Module resolveNode(String name)
{
String expandedName = args.getProperties().expand(name);
if (Props.hasPropertyKey(expandedName))
{
StartLog.debug("Not yet able to expand property in: %s",name);
return null;
}
Path file = baseHome.getPath("modules/" + expandedName + ".mod");
if (FS.canReadFile(file))
{
Module parent = registerModule(file);
parent.expandProperties(args.getProperties());
updateParentReferencesTo(parent);
return parent;
}
else
{
if (!Props.hasPropertyKey(name))
{
StartLog.debug("Missing module definition: [ Mod: %s | File: %s ]",name,file);
}
return null;
}
}
@Override
public void onNodeSelected(Module module)
{
StartLog.debug("on node selected: [%s] (%s.mod)",module.getName(),module.getFilesystemRef());
args.parseModule(module);
module.expandProperties(args.getProperties());
}
public List<String> normalizeLibs(List<Module> active)
{
List<String> libs = new ArrayList<>();
for (Module module : active)
{
for (String lib : module.getLibs())
{
if (!libs.contains(lib))
{
libs.add(lib);
}
}
}
return libs;
}
public List<String> normalizeXmls(List<Module> active)
{
List<String> xmls = new ArrayList<>();
for (Module module : active)
{
for (String xml : module.getXmls())
{
if (!xmls.contains(xml))
{
xmls.add(xml);
}
}
}
return xmls;
}
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 GraphException("Cannot read file: " + file);
}
String shortName = baseHome.toShortForm(file);
try
{
StartLog.debug("Registering Module: %s",shortName);
Module module = new Module(baseHome,file);
return register(module);
}
catch (Throwable t)
{
throw new GraphException("Unable to register module: " + shortName,t);
}
}
/**
* Modules can have a different logical name than to their filesystem reference. This updates existing references to
* the filesystem form to use the logical
* name form.
*
* @param module
* the module that might have other modules referring to it.
*/
private void updateParentReferencesTo(Module module)
{
if (module.getName().equals(module.getFilesystemRef()))
{
// nothing to do, its sane already
return;
}
for (Module m : getNodes())
{
List<String> resolvedParents = new ArrayList<>();
for (String parent : m.getParentNames())
{
if (parent.equals(module.getFilesystemRef()))
{
// use logical name instead
resolvedParents.add(module.getName());
}
else
{
// use name as-is
resolvedParents.add(parent);
}
}
m.setParentNames(resolvedParents);
}
}
@Override
public String toString()
{
StringBuilder str = new StringBuilder();
str.append("Modules[");
str.append("count=").append(count());
str.append(",<");
boolean delim = false;
for (String name : getNodeNames())
{
if (delim)
{
str.append(',');
}
str.append(name);
delim = true;
}
str.append(">");
str.append("]");
return str.toString();
}
}