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

org.eclipse.jetty.start.Module Maven / Gradle / Ivy

There is a newer version: 12.1.0.alpha1
Show newest version
//
//  ========================================================================
//  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.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Represents a Module metadata, as defined in Jetty.
 * 
 * 

A module consists of: *

    *
  • A set of jar files, directories and/or jar file patterns to be added to the classpath
  • *
  • A list of XML configuration files
  • *
  • Properties set either directly or via a file of properties
  • *
  • A set of modules names (or capability names) that this module depends on.
  • *
  • A set of capability names that this module provides (including it's own name).
  • *
  • Licence details for using the module
  • *
* Modules are discovered in the ${jetty.home}/modules and * ${jetty.home}/modules directories. A module may refer to * non-discovered dynamic module in a subdirectory, using a property as part or * all of the name. * A module may be enabled, either directly by name or transiently via a dependency * from another module by name or provided capability. */ public class Module { private static final String VERSION_UNSPECIFIED = "9.2"; private static Pattern MOD_NAME = Pattern.compile("^(.*)\\.mod",Pattern.CASE_INSENSITIVE); /** The file of the module */ private final Path _path; /** The name of the module */ private final String _name; /** Is the module dynamic - ie referenced rather than discovered */ private final boolean _dynamic; /** The version of Jetty the module supports */ private Version version; /** The module description */ private final List _description=new ArrayList<>(); /** List of xml configurations for this Module */ private final List _xmls=new ArrayList<>(); /** List of ini template lines */ private final List _iniTemplate=new ArrayList<>(); /** List of default config */ private final List _defaultConfig=new ArrayList<>(); /** List of library options for this Module */ private final List _libs=new ArrayList<>(); /** List of files for this Module */ private final List _files=new ArrayList<>(); /** List of selections for this Module */ private final Set _enables=new HashSet<>(); /** List of provides for this Module */ private final Set _provides=new HashSet<>(); /** Boolean true if directly enabled, false if all selections are transitive */ private boolean _notTransitive; /** Skip File Validation (default: false) */ private boolean _skipFilesValidation = false; /** List of jvm Args */ private final List _jvmArgs=new ArrayList<>(); /** License lines */ private final List _license=new ArrayList<>(); /** Dependencies */ private final Set _depends=new HashSet<>(); /** Optional */ private final Set _optional=new HashSet<>(); public Module(BaseHome basehome, Path path) throws FileNotFoundException, IOException { super(); _path = path; // Module name is the / separated path below the modules directory int m=-1; for (int i=path.getNameCount();i-->0;) { if ("modules".equals(path.getName(i).toString())) { m=i; break; } } if (m<0) throw new IllegalArgumentException("Module not contained within modules directory: "+basehome.toShortForm(path)); String n=path.getName(m+1).toString(); for (int i=m+2;i expander = d->{return props.expand(d);}; Set tmp=_depends.stream().map(expander).collect(Collectors.toSet()); _depends.clear(); _depends.addAll(tmp); tmp=_optional.stream().map(expander).collect(Collectors.toSet()); _optional.clear(); _optional.addAll(tmp); } public List getDefaultConfig() { return _defaultConfig; } public List getIniTemplate() { return _iniTemplate; } public List getFiles() { return _files; } public boolean isSkipFilesValidation() { return _skipFilesValidation; } public List getJvmArgs() { return _jvmArgs; } public List getLibs() { return _libs; } public List getLicense() { return _license; } public List getXmls() { return _xmls; } public Version getVersion() { return version; } public boolean hasDefaultConfig() { return !_defaultConfig.isEmpty(); } public boolean hasIniTemplate() { return !_iniTemplate.isEmpty(); } @Override public int hashCode() { return _name.hashCode(); } public boolean hasLicense() { return (_license != null) && (_license.size() > 0); } /** * Indicates a module that is dynamic in nature * * @return a module where the name is not in the top level of the modules directory */ public boolean isDynamic() { return _dynamic; } public boolean hasFiles(BaseHome baseHome, Props props) { for (String ref : getFiles()) { FileArg farg = new FileArg(this,props.expand(ref)); Path refPath = baseHome.getBasePath(farg.location); if (!Files.exists(refPath)) { return false; } } return true; } public void process(BaseHome basehome) throws FileNotFoundException, IOException { Pattern section = Pattern.compile("\\s*\\[([^]]*)\\]\\s*"); if (!FS.canReadFile(_path)) { StartLog.debug("Skipping read of missing file: %s",basehome.toShortForm(_path)); return; } try (BufferedReader buf = Files.newBufferedReader(_path,StandardCharsets.UTF_8)) { String sectionType = ""; String line; while ((line = buf.readLine()) != null) { line = line.trim(); Matcher sectionMatcher = section.matcher(line); if (sectionMatcher.matches()) { sectionType = sectionMatcher.group(1).trim().toUpperCase(Locale.ENGLISH); } else { // blank lines and comments are valid for ini-template section if ((line.length() == 0) || line.startsWith("#")) { // Remember ini comments and whitespace (empty lines) // for the [ini-template] section if ("INI-TEMPLATE".equals(sectionType)) { _iniTemplate.add(line); } } else { switch (sectionType) { case "": // ignore (this would be entries before first section) break; case "DESCRIPTION": _description.add(line); break; case "DEPEND": case "DEPENDS": _depends.add(line); break; case "FILE": case "FILES": _files.add(line); break; case "DEFAULTS": // old name introduced in 9.2.x case "INI": // new name for 9.3+ _defaultConfig.add(line); break; case "INI-TEMPLATE": _iniTemplate.add(line); break; case "LIB": case "LIBS": _libs.add(line); break; case "LICENSE": case "LICENSES": case "LICENCE": case "LICENCES": _license.add(line); break; case "NAME": StartLog.warn("Deprecated [Name] used in %s",basehome.toShortForm(_path)); _provides.add(line); break; case "PROVIDE": case "PROVIDES": _provides.add(line); break; case "OPTIONAL": _optional.add(line); break; case "EXEC": _jvmArgs.add(line); break; case "VERSION": if (version != null) { throw new IOException("[version] already specified"); } version = new Version(line); break; case "XML": _xmls.add(line); break; default: throw new IOException("Unrecognized Module section: [" + sectionType + "]"); } } } } } if (version == null) { version = new Version(VERSION_UNSPECIFIED); } } public boolean clearTransitiveEnable() { if (_notTransitive) throw new IllegalStateException("Not Transitive"); if (isEnabled()) { _enables.clear(); return true; } return false; } public void setSkipFilesValidation(boolean skipFilesValidation) { this._skipFilesValidation = skipFilesValidation; } @Override public String toString() { StringBuilder str = new StringBuilder(); str.append("Module[").append(getName()); if (isEnabled()) { str.append(",enabled"); } if (isTransitive()) { str.append(",transitive"); } str.append(']'); return str.toString(); } public Set getDepends() { return new HashSet<>(_depends); } public Set getProvides() { return new HashSet<>(_provides); } public Set getOptional() { return new HashSet<>(_optional); } public List getDescription() { return _description; } public boolean isEnabled() { return !_enables.isEmpty(); } public Set getEnableSources() { return new HashSet<>(_enables); } /** * @param source * @param transitive * @return True if the module was not previously enabled */ public boolean enable(String source,boolean transitive) { boolean updated=_enables.isEmpty(); if (transitive) { // Ignore transitive selections if explicitly enabled if (!_notTransitive) _enables.add(source); } else { if (!_notTransitive) { // Ignore transitive selections if explicitly enabled updated=true; _enables.clear(); // clear any transitive enabling } _notTransitive=true; _enables.add(source); } return updated; } public boolean isTransitive() { return isEnabled() && !_notTransitive; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy