Path: blob/master/sourcetools/com.ibm.uma/com/ibm/uma/om/Artifact.java
6004 views
/*******************************************************************************1* Copyright (c) 2001, 2017 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21package com.ibm.uma.om;22import java.util.Hashtable;23import java.util.List;24import java.util.Vector;2526import com.ibm.uma.IPlatform;27import com.ibm.uma.UMA;28import com.ibm.uma.UMAException;2930public class Artifact extends PredicateList {3132public static final int TYPE_SHARED = 1;33public static final int TYPE_STATIC = 2;34public static final int TYPE_EXECUTABLE = 3;35public static final int TYPE_SUBDIR = 4;36public static final int TYPE_BUNDLE = 5;37public static final int TYPE_REFERENCE = 6;38public static final int TYPE_TARGET = 7;3940Hashtable<String, Library> allLibrariesThisArtifactDependsOn;41boolean appendRelease = false;42String bundle;43boolean console = true;44String description;45Vector<Export> exports = new Vector<Export>();46Vector<Flag> flags = new Vector<Flag>();47Vector<Include> includes = new Vector<Include>();48Vector<Library> libraries = new Vector<Library>();49Vector<Command> commands = new Vector<Command>();50Vector<Dependency> dependencies = new Vector<Dependency>();51String loadgroup;52String makefileName;53Vector<MakefileStub> makefileStubs = new Vector<MakefileStub>();54Module module;55String name;56String scope;57boolean includeInAllTarget;58Vector<Object> objects = new Vector<Object>();59Hashtable<String, Option> options = new Hashtable<String,Option>();60boolean[] phases = new boolean[UMA.getUma().getConfiguration().numberOfPhases()];61Vector<Library> staticLinkLibraries = new Vector<Library>();62boolean buildLocal = false;63int type;64Vector<VPath> vpaths = new Vector<VPath>();65public Artifact(Module module) {66super(module.getModulePath());67this.module = module;68for ( int phase=0; phase < UMA.getUma().getConfiguration().numberOfPhases(); phase ++ ) {69phases[phase] = false;70}71}7273public Artifact copy() throws UMAException {74Artifact copy = new Artifact(module);7576// Hashtable<String, Library> allLibrariesThisArtifactDependsOn; Cached when requested, no need to copy it.77// set type78copy.setType(getType());79// copy description80copy.setDescription(getDescription());81// copy commands82for ( Command command : getCommands() ) {83copy.addCommand(command);84}85// copy dependencies86for ( Dependency dependency : getDependendies() ) {87copy.addDependency(dependency);88}89// copy vpaths90for ( VPath vPath : getVPaths() ) {91copy.addVPath(vPath);92}93// copy options94for ( Option option : getOptions().values()) {95copy.addOption(option);96}97// copy phase information98for ( int k=0; k<UMA.getUma().getConfiguration().numberOfPhases(); k++ ) {99copy.setPhase(k, isInPhase(k));100}101// copy includes information102for( Include include : getIncludes() ) {103copy.addInclude(include);104}105// copy library information106for ( Library library : getLibraries() ) {107copy.addLibrary(library);108}109// copy static library information110for ( Library library : getStaticLinkLibraries() ) {111copy.addStaticLinkLibrary(library);112}113// copy object information114for ( Object object : getObjects() ) {115copy.addObject(object);116}117// copy makefile information118for ( MakefileStub makefileStub : getMakefileStubs() ){119copy.addMakefileStub(makefileStub);120}121// copy export information122for ( Export export : getExports() ) {123copy.addExport(export);124}125// copy flags126for ( Flag flag : getFlags() ) {127copy.addFlag(flag);128}129// set the scope130copy.setScope(getScope());131// set artifact name132copy.setName(getTargetName());133// set makefile name134copy.setMakefileName(getMakefileName());135136// set various flags137copy.setBundle(getBundle());138copy.setLoadgroup(getLoadGroup());139copy.setBuildLocal(getBuildLocal());140copy.setAppendRelease(appendRelease());141copy.setConsoleApplication(isConsoleApplication());142copy.setIncludeInAllTarget(includeInAllTarget());143144return copy;145}146147public String getScope() {148return scope;149}150151152public void setScope(String scope) {153this.scope = scope;154if (makefileName != null && !makefileName.startsWith(scope+"_")) {155makefileName = scope + "_" + makefileName;156}157}158159public void setIncludeInAllTarget(boolean includeInAllTarget) {160this.includeInAllTarget = includeInAllTarget;161}162163public boolean includeInAllTarget() {164return includeInAllTarget;165}166167public void addExport(Export export) {168exports.add(export);169}170171public void addFlag(Flag flag) {172flags.add(flag);173}174175public void addInclude(Include include) {176includes.add(include);177}178179public void addCommand(Command command) {180commands.add(command);181}182183public void addDependency(Dependency dependency) {184dependencies.add(dependency);185}186187public void addLibrary(Library library) {188libraries.add(library);189}190191public void addMakefileStub(MakefileStub makefileStub) {192makefileStubs.add(makefileStub);193}194195public void addObject(Object object) {196objects.add(object);197}198199public void addOption(Option option) {200options.put(option.getName(), option);201}202203public void addStaticLinkLibrary(Library library) {204staticLinkLibraries.add(library);205}206207public void addVPath(VPath vpath) {208vpaths.add(vpath);209}210211public boolean appendRelease() {212return appendRelease;213}214215@Override216public boolean evaluate() throws UMAException {217/*218* short circuit evaluation if this artifact was specified to be always excluded.219*/220List<String> excludedArtifacts = UMA.getUma().getConfiguration().getExcludedArtifacts();221if ( excludedArtifacts.contains(name)) return false;222return super.evaluate();223}224225public boolean flagSet(String flag) throws UMAException {226Option option = options.get(flag);227if ( option == null || !option.evaluate() ) return false;228return true;229}230231public String[] getAllLibrariesInTree() {232String[] libs = new String[libraries.size()];233for ( int i=0; i<libraries.size(); i++ ) {234libs[i] = libraries.elementAt(i).getName();235}236return libs;237}238239public Hashtable<String, Library> getAllLibrariesThisArtifactDependsOn() throws UMAException {240if ( allLibrariesThisArtifactDependsOn == null ) {241allLibrariesThisArtifactDependsOn = new Hashtable<String, Library>();242for ( Library lib : libraries ) {243244/* Check to see if the library should be included */245if (!lib.evaluate()) {246continue;247}248249if ( allLibrariesThisArtifactDependsOn.get(lib.getName()) == null ) {250switch ( lib.getType() ) {251case Library.TYPE_BUILD:252Artifact artifact = UMA.getUma().getArtifact(lib.getName());253if ( artifact == null || !artifact.evaluate()) {254// this lib is not being built ignore it255continue;256}257258if ( lib.getName().equals(getArtifactKey()) ) {259throw new UMAException("circular dependency artifact [" + getArtifactKey()+ "] defined in [" + getContainingFile() + "] depends on itself via artifact [" + artifact.getArtifactKey()+ "] defined in [" + artifact.getContainingFile() + "]" );260}261262if ( artifact.isInBundle() && (!isInBundle() || !artifact.getBundle().equalsIgnoreCase(getBundle()))) {263if ( allLibrariesThisArtifactDependsOn.get(artifact.getBundle()) == null ) {264Library bundleLib = new Library(containingFile);265bundleLib.setName(artifact.getBundle());266bundleLib.setType("build");267allLibrariesThisArtifactDependsOn.put(artifact.getBundle(), bundleLib);268}269} else {270allLibrariesThisArtifactDependsOn.put(lib.getName(), lib);271}272273Hashtable<String, Library> hasht = artifact.getAllLibrariesThisArtifactDependsOn();274for ( String libname : hasht.keySet() ) {275if ( allLibrariesThisArtifactDependsOn.get(libname) == null ) {276if ( libname.equals(getArtifactKey()) ) {277throw new UMAException("circular dependency artifact [" + getArtifactKey()+ "] defined in [" + getContainingFile() + "] depends on itself via artifact [" + artifact.getArtifactKey()+ "] defined in [" + artifact.getContainingFile() + "]" );278}279allLibrariesThisArtifactDependsOn.put(libname, hasht.get(libname));280}281}282break;283default:284allLibrariesThisArtifactDependsOn.put(lib.getName(), lib);285break;286}287}288}289}290return allLibrariesThisArtifactDependsOn;291}292293public String getBundle() {294return bundle;295}296297public Module getContainingModule() {298return module;299}300301public String[] getData(String name) throws UMAException {302Option option = options.get(name);303if ( option == null || !option.evaluate() ) return null;304return option.getData();305}306307public String getDescription() {308return description;309}310311public Vector<Export> getExportedFunctions() throws UMAException {312if ( type == TYPE_BUNDLE ) {313return getBundleExportedFunctions();314} else {315return getArtifactExportedFunctions();316}317}318319public Vector<Export> getArtifactExportedFunctions() throws UMAException {320Vector<Export> ef = new Vector<Export>();321for ( Export export : exports ) {322if ( !export.evaluate() ) continue;323switch ( export.getType() ) {324case Export.TYPE_FUNCTION:325ef.add(export);326break;327case Export.TYPE_GROUP:328Exports expGroup = module.getExports().get(export.getExport());329if ( expGroup == null ) {330throw new UMAException("Error: export group " + export.getExport() + " not found in module " + module.getModulePath() + ".");331}332if ( expGroup.evaluate() ) {333for ( Export exp : expGroup.getExports() ) {334if ( !exp.evaluate() ) continue;335switch ( exp.getType() ) {336case Export.TYPE_FUNCTION:337ef.add(exp);338break;339case Export.TYPE_GROUP:340throw new UMAException("Error: export group " + export.getExport() + " refers to another group [" + exp.getExport() +"] in module " + module.getModulePath() + ".");341}342}343}344}345}346return ef;347}348349private Export addArtifactPrefix(Artifact artifact, Export export)350{351String exportName = export.getExport();352if (exportName.equals("JVM_OnLoad") || exportName.equals("JVM_OnUnload") || exportName.equals("J9VMDllMain") || exportName.equals("JNI_OnLoad") || exportName.equals("JNI_OnUnload") ) {353Export copy = new Export(export.containingFile);354copy.setExport(artifact.getTargetName() + "_" + exportName);355copy.setType(export.getType());356return copy;357}358359return export;360}361362public Vector<Export> getBundleExportedFunctions() throws UMAException {363Vector<Export> ef = new Vector<Export>();364Vector<Artifact> bundleArtifacts = getAllArtifactsInThisBundle();365for ( Artifact artifact : bundleArtifacts ) {366for ( Export export : artifact.exports ) {367if ( !export.evaluate() ) continue;368switch ( export.getType() ) {369case Export.TYPE_FUNCTION:370ef.add( addArtifactPrefix(artifact, export) );371break;372case Export.TYPE_GROUP:373Exports expGroup = artifact.module.getExports().get(export.getExport());374if ( expGroup == null ) {375throw new UMAException("Error: export group " + export.getExport() + " not found in module " + module.getModulePath() + ".");376}377if ( expGroup.evaluate() ) {378for ( Export exp : expGroup.getExports() ) {379if ( !exp.evaluate() ) continue;380switch ( exp.getType() ) {381case Export.TYPE_FUNCTION:382ef.add( addArtifactPrefix(artifact, exp) );383break;384case Export.TYPE_GROUP:385throw new UMAException("Error: export group " + export.getExport() + " refers to another group [" + exp.getExport() +"] in module " + module.getModulePath() + ".");386}387}388}389}390}391}392return ef;393}394395396public Vector<Export> getExports() {397return exports;398}399400public Vector<Flag> getFlags() throws UMAException {401Vector<Flag> processedFlags = flags;402if (flags.size() > 0) {403processedFlags = new Vector<Flag>();404for (Flag f : flags) {405if (f == null) {406continue;407}408//System.out.println("Flag: " + (f == null ? "null" : f.getName()));409switch(f.type) {410case Flag.SINGLE:411processedFlags.add(f);412break;413case Flag.GROUP:414//System.out.println("Group Flag: " + f.getName() + " group:"+ f.groupName);415Flags group = module.getFlags().get(f.groupName);416if (group == null) {417throw new UMAException("Error: flags group " + f.groupName + " not found in module " + module.getModulePath() + ".");418}419for (Flag groupFlag : group.getFlags()) {420//System.out.println("Group Flag: " + groupFlag.getName() + " group:"+ f.groupName);421switch(groupFlag.type) {422case Flag.SINGLE:423processedFlags.add(groupFlag);424break;425case Flag.GROUP:426throw new UMAException("Error: flags group " + groupFlag.groupName + " inside group in " + module.getModulePath() + ".");427}428}429break;430}431}432}433return processedFlags;434}435436public Vector<Include> getIncludes() {437return includes;438}439440public Vector<Command> getCommands() {441return commands;442}443444public Vector<Dependency> getDependendies() {445return dependencies;446}447448449public String getArtifactKey() {450String artifactKey = getTargetName();451if ( getScope() != null ) {452artifactKey = getScope() + "_" + artifactKey;453}454return artifactKey;455}456457public Hashtable<String, Artifact> getAllArtifactsInThisBundleInHashtable() throws UMAException {458Hashtable<String, Artifact> table = new Hashtable<String, Artifact>();459for ( Artifact artifact : getAllArtifactsInThisBundle() ) {460table.put(artifact.getArtifactKey(), artifact);461}462return table;463}464465public Vector<Artifact> getAllArtifactsInThisBundle() throws UMAException {466Vector<Artifact> artifactsInThisBundle = new Vector<Artifact>();467for ( Module module : UMA.getUma().getModules() ) {468if (!module.evaluate()) continue;469for ( Artifact artifact : module.getArtifacts() ) {470if (!artifact.evaluate()) continue;471String bundle = artifact.getBundle();472if (bundle != null && bundle.equalsIgnoreCase(getTargetName())) {473artifactsInThisBundle.add(artifact);474}475}476}477return artifactsInThisBundle;478}479480public Boolean isInBundle() throws UMAException {481if ( getBundle() != null ) {482Artifact bundleArtifact = UMA.getUma().getBundleArtifact(getBundle());483if ( bundleArtifact != null && bundleArtifact.evaluate() ) {484return true;485}486}487return false;488}489490public boolean isBundle() {491return type == TYPE_BUNDLE;492}493494public Vector<Library> getLibraries() throws UMAException {495if ( type == TYPE_BUNDLE ) {496//TODO cache this result instead calculating it everytime497Vector<Library> bundleLibraries = new Vector<Library>(libraries);498Vector<Artifact> bundleArtifacts = getAllArtifactsInThisBundle();499for ( Artifact artifact : bundleArtifacts ) {500Library artifactLib = new Library(containingFile);501artifactLib.setName(artifact.getTargetName());502artifactLib.setType("build");503bundleLibraries.add(artifactLib);504bundleLibraries.addAll(artifact.getLibraries());505}506return bundleLibraries;507}508return libraries;509}510511public String getLoadGroup() {512return loadgroup;513}514515public String getMakefileName() {516return makefileName;517}518519public String getMakefileFileName() throws UMAException {520if (module.requiresDispatchMakefile()) return getMakefileName() + ".mk";521return "makefile";522}523524public Vector<MakefileStub> getMakefileStubs() {525return makefileStubs;526}527public Vector<Object> getObjects() {528return objects;529}530531public Vector<VPath> getVPaths() {532return vpaths;533}534535public Hashtable<String, Option> getOptions() {536return options;537}538539public Vector<Library> getStaticLinkLibraries() throws UMAException {540Vector<Library> combinedStaticLibraries = new Vector<Library>(staticLinkLibraries);541for ( Library library : libraries ) {542if ( !library.evaluate() ) continue;543if ( library.getType() == Library.TYPE_BUILD ) {544Artifact libArtifact = UMA.getUma().getArtifact(library.getName());545if ( libArtifact == null || !libArtifact.evaluate() ) continue;546if ( libArtifact.isInBundle() ) {547// need to augment static libraries with libraries that make548// up this bundle549Library refLibrary = new Library("static-link-created");550refLibrary.setName(libArtifact.getTargetName());551combinedStaticLibraries.add(refLibrary);552}553}554555}556return combinedStaticLibraries;557}558559public String getTargetName() {560return name;561}562563public String getTargetNameWithScope() {564if (scope == null ) return getTargetName();565return scope + "_" + name;566}567568public String getTargetPath() {569if (buildLocal) {570return module.getFullName() + "/";571}572return null;573}574575public boolean getBuildLocal() {576return buildLocal;577}578579public String getTargetPath(IPlatform platform) throws UMAException {580if ( getTargetPath() != null ) return getTargetPath();581switch ( type ) {582case TYPE_EXECUTABLE:583return platform.getExecutablePath();584case TYPE_BUNDLE: // fall-thru585case TYPE_SHARED:586return platform.getSharedLibPath();587case TYPE_STATIC:588return platform.getStaticLibPath();589}590return "";591}592593public String getTargetPathAsStatic(IPlatform platform) throws UMAException {594if ( getTargetPath() != null ) return getTargetPath();595return platform.getStaticLibPath();596}597598public int getType() throws UMAException {599if ( type == TYPE_SHARED && isInBundle() ) {600type = TYPE_STATIC;601}602return type;603}604605public boolean isConsoleApplication() {606return console;607}608609public boolean isInPhase(int phase) throws UMAException {610return phases[phase];611}612613public boolean isLibDefinedInTree( String lib ) {614return lib.equals(name);615}616public boolean requires(Artifact oa) throws UMAException {617for ( Library library : libraries ) {618if (!library.evaluate()) continue;619if ( library.getName().equalsIgnoreCase(oa.getTargetName()) ) {620return true;621}622Artifact libArt = UMA.getUma().getArtifact(library.getName());623if ( libArt != null && libArt.evaluate() && libArt.requires(oa) ) {624return true;625}626}627return false;628}629public void setAppendRelease(boolean appendRelease) {630this.appendRelease = appendRelease;631}632public void setBundle(String bundle) {633this.bundle = bundle;634}635public void setConsoleApplication( boolean console ) {636this.console = console;637}638639public void setDescription(String desc) {640description = desc;641}642643public void setLoadgroup(String loadgroup) {644this.loadgroup = loadgroup;645if (loadgroup == null || loadgroup.equals("")) {646this.loadgroup = getTargetName();647}648}649650public void setMakefileName(String nm) {651makefileName = nm;652if (scope != null && !makefileName.startsWith(scope+"_")) {653makefileName = scope + "_" + makefileName;654}655}656657public void setName(String name) {658this.name = name;659// default is to set makefileName to name660makefileName = name;661if (scope != null && !makefileName.startsWith(scope+"_")) {662makefileName = scope + "_" + makefileName;663}664}665666public void setPhase(int phase, boolean value) {667try {668phases[phase] = value;669} catch (ArrayIndexOutOfBoundsException e) {670// Bad phase passed in, ignore.671}672}673674public void setBuildLocal(boolean buildLocal) {675this.buildLocal = buildLocal;676}677678public void setType(String type) {679if ( type.equalsIgnoreCase("shared")) {680this.type = TYPE_SHARED;681} else if ( type.equalsIgnoreCase("static")) {682this.type = TYPE_STATIC;683} else if ( type.equalsIgnoreCase("executable")) {684this.type = TYPE_EXECUTABLE;685} else if ( type.equalsIgnoreCase("subdir") ) {686this.type = TYPE_SUBDIR;687} else if ( type.equalsIgnoreCase("bundle") ) {688this.type = TYPE_BUNDLE;689} else if ( type.equalsIgnoreCase("reference") ) {690this.type = TYPE_REFERENCE;691} else if ( type.equalsIgnoreCase("target") ) {692this.type = TYPE_TARGET;693}694}695696private void setType(int type) {697this.type = type;698}699700701}702703704