708 lines
24 KiB
Java
Executable File
708 lines
24 KiB
Java
Executable File
/*
|
|
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation; either version 2.1 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
package com.arsdigita.packaging;
|
|
|
|
import com.arsdigita.loader.PackageLoader;
|
|
import com.arsdigita.persistence.ConnectionSource;
|
|
import com.arsdigita.persistence.DedicatedConnectionSource;
|
|
import com.arsdigita.persistence.OID;
|
|
import com.arsdigita.persistence.Session;
|
|
import com.arsdigita.persistence.SessionManager;
|
|
import com.arsdigita.persistence.metadata.MetadataRoot;
|
|
import com.arsdigita.persistence.pdl.PDLCompiler;
|
|
// pboy (Jan.09): deprecated classes and methods removed,
|
|
// comments should be deleted after extensiv testing
|
|
// deprecated, no replacement specified by author,
|
|
// created InteractiveParameterReader analogous to CompoundParameterReader
|
|
//import com.arsdigita.runtime.InteractiveParameterLoader;
|
|
import com.arsdigita.runtime.InteractiveParameterReader;
|
|
import com.arsdigita.runtime.ConfigRegistry;
|
|
import com.arsdigita.runtime.RegistryConfig;
|
|
import com.arsdigita.runtime.RuntimeConfig;
|
|
import com.arsdigita.runtime.Startup;
|
|
import com.arsdigita.util.UncheckedWrapperException;
|
|
// deprecated, use c.ad.util.JavaPropertyReader instead
|
|
// import com.arsdigita.util.config.JavaPropertyLoader;
|
|
import com.arsdigita.util.JavaPropertyReader;
|
|
import com.arsdigita.util.jdbc.Connections;
|
|
// deprecated:
|
|
// import com.arsdigita.util.parameter.CompoundParameterLoader;
|
|
import com.arsdigita.util.parameter.CompoundParameterReader;
|
|
import com.arsdigita.util.parameter.Parameter;
|
|
import com.arsdigita.util.parameter.ParameterContext;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStreamWriter;
|
|
import java.io.Writer;
|
|
import java.sql.Connection;
|
|
import java.sql.SQLException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Properties;
|
|
import java.util.Set;
|
|
import org.apache.commons.cli.CommandLine;
|
|
import org.apache.commons.cli.OptionBuilder;
|
|
import org.apache.commons.cli.Options;
|
|
import org.apache.commons.cli.ParseException;
|
|
import org.apache.commons.cli.PosixParser;
|
|
|
|
/**
|
|
* PackageTool worker class, implements the "load" command.
|
|
*
|
|
* Loads the database schema and initial content.
|
|
*
|
|
* Called by PackageTool
|
|
*
|
|
* @author Rafael H. Schloming <rhs@mit.edu>
|
|
* @version $Revision: #29 $ $Date: 2004/08/16 $
|
|
**/
|
|
|
|
class Load extends Command {
|
|
|
|
public final static String versionId =
|
|
"$Id: Load.java 736 2005-09-01 10:46:05Z sskracic $" +
|
|
" by $Author: sskracic $, " +
|
|
"$DateTime: 2004/08/16 18:10:38 $";
|
|
|
|
private static final Options OPTIONS = getOptions();
|
|
|
|
static {
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg(false)
|
|
.withLongOpt("config")
|
|
.withDescription("Load configuration")
|
|
.create());
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg(false)
|
|
.withLongOpt("schema")
|
|
.withDescription("Load schema")
|
|
.create());
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg(false)
|
|
.withLongOpt("data")
|
|
.withDescription("Load data")
|
|
.create());
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg(false)
|
|
.withLongOpt("init")
|
|
.withDescription("Load initializers")
|
|
.create());
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg()
|
|
.withLongOpt("parameter-file")
|
|
.withArgName("FILE")
|
|
.withDescription("Use key-value pairs from FILE")
|
|
.create());
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg(false)
|
|
.withLongOpt("interactive")
|
|
.withDescription("Prompt for required parameter values")
|
|
.create());
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArgs()
|
|
.withLongOpt("parameters")
|
|
.withArgName("KEY=VALUE ...")
|
|
.withDescription("Use key-value pairs from command line")
|
|
.create());
|
|
OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg(false)
|
|
.withLongOpt("recursive")
|
|
.withDescription("Recursively load required packages")
|
|
.create());
|
|
/*OPTIONS.addOption
|
|
(OptionBuilder
|
|
.hasArg()
|
|
.withLongOpt("log")
|
|
.withArgName("FILE")
|
|
.withDescription("Log parameter values as key-value " +
|
|
"pairs in FILE")
|
|
.create());*/
|
|
}
|
|
|
|
public Load() {
|
|
super("load", "Load a CCM package");
|
|
}
|
|
|
|
public boolean run(String[] args) {
|
|
CommandLine line;
|
|
|
|
try {
|
|
line = new PosixParser().parse(OPTIONS, args);
|
|
} catch (ParseException e) {
|
|
System.err.println(e.getMessage());
|
|
return false;
|
|
}
|
|
|
|
List packages = line.getArgList();
|
|
if (packages.isEmpty()) {
|
|
usage(OPTIONS, System.err, "PACKAGE-KEYS");
|
|
return false;
|
|
}
|
|
|
|
if (line.hasOption("usage") || line.hasOption("help")) {
|
|
usage(OPTIONS, System.out, "PACKAGE-KEYS");
|
|
return true;
|
|
}
|
|
|
|
final boolean all = !(line.hasOption("config")
|
|
|| line.hasOption("schema")
|
|
|| line.hasOption("data")
|
|
|| line.hasOption("init"));
|
|
|
|
RegistryConfig rc = new RegistryConfig();
|
|
rc.load();
|
|
List loaded = Arrays.asList(rc.getPackages());
|
|
|
|
Map loaders = new HashMap();
|
|
List keys = new ArrayList();
|
|
keys.addAll(packages);
|
|
boolean err = false;
|
|
while (!keys.isEmpty()) {
|
|
String key = (String) keys.remove(0);
|
|
if (loaders.containsKey(key)) { continue; }
|
|
Loader l = Loader.get(key);
|
|
if (l == null) {
|
|
System.err.println("unable to locate package: " + key);
|
|
err = true;
|
|
} else {
|
|
loaders.put(key, l);
|
|
if (line.hasOption("recursive")) {
|
|
keys.addAll(l.getInfo().getRequiredPackages());
|
|
}
|
|
}
|
|
}
|
|
if (err) { return false; }
|
|
|
|
Loader[] sorted = (Loader[]) loaders.values().toArray
|
|
(new Loader[loaders.size()]);
|
|
sort(sorted);
|
|
|
|
if (all) {
|
|
List missing = new ArrayList();
|
|
addTo(missing, getRequiredPackages(sorted));
|
|
missing.removeAll(getProvidedPackages(sorted));
|
|
missing.removeAll(loaded);
|
|
List conflicts = new ArrayList(loaded);
|
|
conflicts.retainAll(getProvidedPackages(sorted));
|
|
if (!missing.isEmpty()) {
|
|
System.err.println("required packages: " + missing);
|
|
}
|
|
if (!conflicts.isEmpty()) {
|
|
System.err.println("conflicting packages: " + conflicts);
|
|
}
|
|
if (missing.size() + conflicts.size() > 0) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
ParameterMap contexts = new ParameterMap();
|
|
|
|
Properties parameters = new Properties();
|
|
CompoundParameterReader cpr = new CompoundParameterReader();
|
|
if (line.hasOption("parameter-file")) {
|
|
String file = line.getOptionValue("parameter-file");
|
|
try {
|
|
InputStream fis = new FileInputStream(file);
|
|
parameters.load(fis);
|
|
fis.close();
|
|
} catch (IOException e) {
|
|
System.err.println(e.getMessage());
|
|
return false;
|
|
}
|
|
// deprecated, use JavaPropertyReader instead
|
|
// cpr.add(new JavaPropertyLoader(parameters));
|
|
cpr.add(new JavaPropertyReader(parameters));
|
|
}
|
|
if (line.hasOption("parameters")) {
|
|
Properties props = props(line.getOptionValues("parameters"));
|
|
// deprecated, use JavaPropertyReader instead
|
|
// cpr.add(new JavaPropertyLoader(props));
|
|
cpr.add(new JavaPropertyReader(props));
|
|
parameters.putAll(props);
|
|
}
|
|
if (line.hasOption("interactive")) {
|
|
cpr.add(new InteractiveParameterReader(System.in, System.out));
|
|
}
|
|
|
|
Config config = null;
|
|
try {
|
|
if (all || line.hasOption("config")) {
|
|
ConfigRegistry reg = new ConfigRegistry();
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
if (!reg.getPackages().contains(sorted[i].getKey())) {
|
|
reg.initialize(sorted[i].getKey());
|
|
}
|
|
}
|
|
config = new Config(reg);
|
|
config.load(System.err);
|
|
|
|
Parameter param = config.getParameter("waf.config.packages");
|
|
ParameterContext ctx = config.getContainer(param);
|
|
String[] pkgs = (String[]) ctx.get(param);
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
if (!contains(pkgs, sorted[i].getKey())) {
|
|
pkgs = concat(pkgs, new String[] { sorted[i].getKey() });
|
|
}
|
|
}
|
|
ctx.set(param, pkgs);
|
|
|
|
contexts.addContexts(config.getContexts());
|
|
}
|
|
|
|
if (all || line.hasOption("data")) {
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
contexts.addContexts(sorted[i].getScripts());
|
|
}
|
|
}
|
|
|
|
if (!contexts.load(new JavaPropertyReader(parameters), System.err)) {
|
|
return false;
|
|
}
|
|
|
|
if (line.hasOption("interactive")) {
|
|
ParameterEditor editor =
|
|
new ParameterEditor(contexts, System.in, System.out);
|
|
if (!editor.edit()) { return true; }
|
|
} else if (!contexts.validate(System.err)) {
|
|
return false;
|
|
}
|
|
|
|
if (!saveConfig(config)) {
|
|
return false;
|
|
}
|
|
|
|
Session ssn = null;
|
|
if (all || line.hasOption("schema") || line.hasOption("data")) {
|
|
|
|
Check checkdb = new CheckDB();
|
|
checkdb.run(null);
|
|
if (checkdb.getStatus() == null
|
|
|| checkdb.getStatus().equals(Check.FAIL)) {
|
|
rollbackConfig(config,packages);
|
|
return false;
|
|
}
|
|
|
|
if (all || line.hasOption("schema")) {
|
|
boolean passed = true;
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
passed &= sorted[i].checkSchema();
|
|
}
|
|
if (!passed) {
|
|
rollbackConfig(config,packages);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Connection conn =
|
|
Connections.acquire(RuntimeConfig.getConfig().getJDBCURL());
|
|
|
|
List required = new ArrayList();
|
|
addTo(required, getRequiredTables(sorted));
|
|
List provided = new ArrayList();
|
|
|
|
if (all || line.hasOption("schema")) {
|
|
required.removeAll(getProvidedTables(sorted));
|
|
addTo(provided, getProvidedTables(sorted));
|
|
} else if (line.hasOption("data")) {
|
|
addTo(required, getProvidedTables(sorted));
|
|
}
|
|
|
|
List missing = getMissing(conn, required);
|
|
List conflicts = getConflicts(conn, provided);
|
|
|
|
if (!missing.isEmpty()) {
|
|
System.err.println("required tables: " + missing);
|
|
}
|
|
|
|
if (!conflicts.isEmpty()) {
|
|
System.err.println("conflicting tables: " + conflicts);
|
|
}
|
|
|
|
if (conflicts.size() > 0 || missing.size() > 0) {
|
|
rollbackConfig(config,packages);
|
|
return false;
|
|
}
|
|
|
|
if (PackageLoader.exists(conn, "inits")
|
|
&& (line.hasOption("init") || all)) {
|
|
final boolean success = checkInitializerDependencies
|
|
(sorted);
|
|
|
|
if (!success) {
|
|
rollbackConfig(config,packages);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (all || line.hasOption("schema")) {
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
sorted[i].loadSchema(conn);
|
|
}
|
|
try {
|
|
conn.commit();
|
|
} catch (SQLException e) {
|
|
System.err.println(e.getMessage());
|
|
rollbackConfig(config,packages);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
if (all || line.hasOption("data")) {
|
|
if (ssn == null) {
|
|
new Startup().run();
|
|
ssn = SessionManager.getSession();
|
|
}
|
|
|
|
boolean passed = true;
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
passed &= sorted[i].checkData(ssn);
|
|
}
|
|
if (!passed) {
|
|
rollbackConfig(config,packages);
|
|
return false;
|
|
}
|
|
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
sorted[i].loadData(ssn, cpr);
|
|
}
|
|
}
|
|
}
|
|
if (all || line.hasOption("init")) {
|
|
if (ssn == null) {
|
|
new Startup().run();
|
|
ssn = SessionManager.getSession();
|
|
}
|
|
for (int i = 0; i < sorted.length; i++) {
|
|
sorted[i].loadInits(ssn);
|
|
}
|
|
}
|
|
} catch (Throwable t) {
|
|
t.printStackTrace(System.err);
|
|
rollbackConfig(config,packages);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private boolean checkInitializerDependencies(final Loader[] sorted) {
|
|
final List required = new ArrayList();
|
|
final List provided = new ArrayList();
|
|
addTo(required, getRequiredInitializers(sorted));
|
|
required.removeAll(getProvidedInitializers(sorted));
|
|
addTo(provided, getProvidedInitializers(sorted));
|
|
|
|
final Session boot = session();
|
|
final List missing = getMissing(boot, required);
|
|
final List conflicts = getConflicts(boot, provided);
|
|
|
|
if (!missing.isEmpty()) {
|
|
System.err.println("required initializers: " + missing);
|
|
return false;
|
|
}
|
|
|
|
if (!conflicts.isEmpty()) {
|
|
System.err.println("conflicting initializers: " + conflicts);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean saveConfig(Config config) {
|
|
if (config != null) {
|
|
try {
|
|
config.save();
|
|
} catch (IOException e) {
|
|
System.err.println(e.getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void rollbackConfig(Config config, List packages) {
|
|
if (config != null) {
|
|
Parameter param = config.getParameter("waf.config.packages");
|
|
ParameterContext ctx = config.getContainer(param);
|
|
String[] pkgs = (String[]) ctx.get(param);
|
|
LinkedList original = new LinkedList();
|
|
for (int i = 0; i < pkgs.length; i++) {
|
|
boolean isnew = false;
|
|
for (int j = 0; j < packages.size(); j++) {
|
|
// Operator == compares object identity.
|
|
// comparison here refers to package names, so an
|
|
// object comparison will never be true.
|
|
// instead: equals()
|
|
// if (pkgs[i].toString() == packages.get(j).toString()) {
|
|
if (pkgs[i].toString().equals(packages.get(j).toString())) {
|
|
isnew = true;
|
|
}
|
|
}
|
|
if (!isnew) {
|
|
original.add(pkgs[i]);
|
|
}
|
|
}
|
|
String[] orig = new String[original.size()];
|
|
for (int i = 0; i < original.size(); i++) {
|
|
orig[i] = (String)original.get(i);
|
|
}
|
|
ctx.set(param, orig);
|
|
saveConfig(config);
|
|
}
|
|
}
|
|
|
|
private static List getMissing(Connection conn, List tables) {
|
|
List missing = new ArrayList();
|
|
for (Iterator it = tables.iterator(); it.hasNext(); ) {
|
|
String table = (String) it.next();
|
|
if (!PackageLoader.exists(conn, table)) {
|
|
missing.add(table);
|
|
}
|
|
}
|
|
return missing;
|
|
}
|
|
|
|
private static List getConflicts(Connection conn, List tables) {
|
|
List conflicts = new ArrayList();
|
|
for (Iterator it = tables.iterator(); it.hasNext(); ) {
|
|
String table = (String) it.next();
|
|
if (PackageLoader.exists(conn, table)) {
|
|
conflicts.add(table);
|
|
}
|
|
}
|
|
return conflicts;
|
|
}
|
|
|
|
private static final String INIT = "com.arsdigita.runtime.Initializer";
|
|
|
|
private static List getMissing(Session ssn, List inits) {
|
|
List missing = new ArrayList();
|
|
for (Iterator it = inits.iterator(); it.hasNext(); ) {
|
|
String init = (String) it.next();
|
|
OID oid = new OID(ssn.getMetadataRoot().getObjectType(INIT), init);
|
|
if (ssn.retrieve(oid) == null) {
|
|
missing.add(init);
|
|
}
|
|
}
|
|
return missing;
|
|
}
|
|
|
|
private static List getConflicts(Session ssn, List inits) {
|
|
List conflicts = new ArrayList();
|
|
for (Iterator it = inits.iterator(); it.hasNext(); ) {
|
|
String init = (String) it.next();
|
|
OID oid = new OID(ssn.getMetadataRoot().getObjectType(INIT), init);
|
|
if (ssn.retrieve(oid) != null) {
|
|
conflicts.add(init);
|
|
}
|
|
}
|
|
return conflicts;
|
|
}
|
|
|
|
private static String[] concat(String[] a, String[] b) {
|
|
if (a == null) { return b; }
|
|
if (b == null) { return a; }
|
|
String[] result = new String[a.length + b.length];
|
|
System.arraycopy(a, 0, result, 0, a.length);
|
|
System.arraycopy(b, 0, result, a.length, b.length);
|
|
return result;
|
|
}
|
|
|
|
private static boolean contains(String[] array, String str) {
|
|
for (int i = 0; i < array.length; i++) {
|
|
if (array[i].equals(str)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static Session session() {
|
|
Session ssn = SessionManager.getSession("loader");
|
|
if (ssn == null) {
|
|
String pdl = "/com/arsdigita/runtime/Initializer.pdl";
|
|
MetadataRoot root = new MetadataRoot();
|
|
PDLCompiler compiler = new PDLCompiler();
|
|
compiler.parse
|
|
(new InputStreamReader
|
|
(Load.class.getResourceAsStream(pdl)),
|
|
pdl);
|
|
compiler.emit(root);
|
|
ConnectionSource source = new DedicatedConnectionSource
|
|
(RuntimeConfig.getConfig().getJDBCURL());
|
|
ssn = SessionManager.open("loader", root, source);
|
|
}
|
|
|
|
return ssn;
|
|
}
|
|
|
|
static Properties props(String[] args) {
|
|
try {
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
Writer w = new OutputStreamWriter(baos);
|
|
for (int i = 0; i < args.length; i++) {
|
|
w.write(args[i]);
|
|
w.write("\n");
|
|
}
|
|
|
|
w.flush();
|
|
|
|
Properties props = new Properties();
|
|
props.load(new ByteArrayInputStream(baos.toByteArray()));
|
|
return props;
|
|
} catch (IOException e) {
|
|
throw new UncheckedWrapperException(e);
|
|
}
|
|
}
|
|
|
|
private static void sort(Loader[] loaders) {
|
|
Set all = new HashSet();
|
|
for (int i = 0; i < loaders.length; i++) {
|
|
all.addAll(loaders[i].getProvided());
|
|
}
|
|
|
|
Set provided = new HashSet();
|
|
List sorted = new ArrayList();
|
|
List in = new ArrayList(Arrays.asList(loaders));
|
|
int before;
|
|
do {
|
|
before = in.size();
|
|
for (Iterator it = in.iterator(); it.hasNext(); ) {
|
|
Loader loader = (Loader) it.next();
|
|
Set required = loader.getRequired();
|
|
required.retainAll(all);
|
|
if (provided.containsAll(required)) {
|
|
sorted.add(loader);
|
|
provided.addAll(loader.getProvided());
|
|
it.remove();
|
|
}
|
|
}
|
|
} while (in.size() < before);
|
|
|
|
if (in.size() > 0) {
|
|
throw new IllegalStateException
|
|
("circular dependencies: " + in);
|
|
}
|
|
|
|
int index = 0;
|
|
for (Iterator it = sorted.iterator(); it.hasNext(); ) {
|
|
loaders[index++] = (Loader) it.next();
|
|
}
|
|
}
|
|
|
|
private static final int REQ_TABLE = 0;
|
|
private static final int REQ_INITIALIZER = 1;
|
|
private static final int REQ_PACKAGE = 2;
|
|
private static final int PROV_TABLE = 3;
|
|
private static final int PROV_INITIALIZER = 4;
|
|
private static final int PROV_PACKAGE = 5;
|
|
|
|
private static List get(Loader[] loaders, int type) {
|
|
ArrayList result = new ArrayList();
|
|
|
|
for (int i = 0; i < loaders.length; i++) {
|
|
LoaderInfo info = loaders[i].getInfo();
|
|
|
|
List c;
|
|
|
|
switch (type) {
|
|
case REQ_TABLE:
|
|
c = info.getRequiredTables();
|
|
break;
|
|
case REQ_INITIALIZER:
|
|
c = info.getRequiredInitializers();
|
|
break;
|
|
case REQ_PACKAGE:
|
|
c = info.getRequiredPackages();
|
|
break;
|
|
case PROV_TABLE:
|
|
c = info.getProvidedTables();
|
|
break;
|
|
case PROV_INITIALIZER:
|
|
c = info.getProvidedInitializers();
|
|
break;
|
|
case PROV_PACKAGE:
|
|
c = new ArrayList();
|
|
c.add(loaders[i].getKey());
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException("unknown type: " + type);
|
|
}
|
|
|
|
addTo(result, c);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private static List getRequiredTables(Loader[] loaders) {
|
|
return get(loaders, REQ_TABLE);
|
|
}
|
|
|
|
private static List getProvidedTables(Loader[] loaders) {
|
|
return get(loaders, PROV_TABLE);
|
|
}
|
|
|
|
private static List getRequiredInitializers(Loader[] loaders) {
|
|
return get(loaders, REQ_INITIALIZER);
|
|
}
|
|
|
|
private static List getProvidedInitializers(Loader[] loaders) {
|
|
return get(loaders, PROV_INITIALIZER);
|
|
}
|
|
|
|
private static List getRequiredPackages(Loader[] loaders) {
|
|
return get(loaders, REQ_PACKAGE);
|
|
}
|
|
|
|
private static List getProvidedPackages(Loader[] loaders) {
|
|
return get(loaders, PROV_PACKAGE);
|
|
}
|
|
|
|
private static void addTo(List a, List b) {
|
|
for (Iterator it = b.iterator(); it.hasNext(); ) {
|
|
Object o = it.next();
|
|
if (!a.contains(o)) {
|
|
a.add(o);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|