Path: blob/master/sourcetools/com.ibm.uma/com/ibm/j9/uma/configuration/ConfigurationImpl.java
6005 views
/*******************************************************************************1* Copyright (c) 2001, 2018 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.j9.uma.configuration;2223import java.io.BufferedReader;24import java.io.File;25import java.io.FileInputStream;26import java.io.FileNotFoundException;27import java.io.IOException;28import java.io.InputStreamReader;29import java.util.Calendar;30import java.util.GregorianCalendar;31import java.util.Hashtable;32import java.util.List;33import java.util.Map;34import java.util.Properties;35import java.util.Set;36import java.util.Vector;37import java.util.regex.Matcher;38import java.util.regex.Pattern;3940import com.ibm.j9.uma.configuration.freemarker.Features;41import com.ibm.j9.uma.configuration.freemarker.Source;42import com.ibm.j9.uma.platform.PlatformOSX;43import com.ibm.j9.uma.platform.PlatformUnix;44import com.ibm.j9.uma.platform.PlatformWindows;45import com.ibm.j9.uma.platform.PlatformZOS;46import com.ibm.j9tools.om.BuildInfo;47import com.ibm.j9tools.om.BuildSpec;48import com.ibm.j9tools.om.ConfigDirectory;49import com.ibm.j9tools.om.Flag;50import com.ibm.j9tools.om.FlagDefinitions;51import com.ibm.j9tools.om.InvalidBuildSpecException;52import com.ibm.j9tools.om.InvalidConfigurationException;53import com.ibm.j9tools.om.OMObjectException;54import com.ibm.j9tools.om.ObjectFactory;55import com.ibm.j9tools.om.Property;56import com.ibm.uma.IConfiguration;57import com.ibm.uma.IPlatform;58import com.ibm.uma.ISinglePredicateEvaluator;59import com.ibm.uma.UMABadPhaseNameException;60import com.ibm.uma.UMAException;61import com.ibm.uma.om.Artifact;62import com.ibm.uma.util.Logger;6364import freemarker.template.SimpleSequence;65import freemarker.template.TemplateModel;66import freemarker.template.TemplateModelIterator;6768public class ConfigurationImpl implements IConfiguration, ISinglePredicateEvaluator {6970String[] phaseList;71String[] excludeArtifacts;7273public int numberOfPhases() {74return phaseList.length;75}7677public String phaseName(int phase) {78if (phase >= numberOfPhases()) {79return "base phase identifier [" + phase + "]";80}81return phaseList[phase];82}8384public int phaseFromString(String phase) throws UMABadPhaseNameException {85for (int i = 0; i < phaseList.length; i++) {86if (phase.equalsIgnoreCase(phaseList[i])) {87return i;88}89}90throw new UMABadPhaseNameException("Unknown phase label: " + phase);91}9293public String[] phases() {94return phaseList;95}9697BuildSpec buildSpec;98FlagDefinitions flagDefs;99IPlatform platform;100BuildInfo buildInfo;101Hashtable<String, String> macroMap = new Hashtable<String, String>();102103public BuildInfo getBuildInfo() {104return buildInfo;105}106107public ConfigurationImpl(String configPath, String buildSpecId, String buildId, String buildDate, String buildTag, String jitVersionFile, String excludeArtifacts) throws UMAException {108try {109ConfigDirectory configDirectory = new ConfigDirectory(configPath);110ObjectFactory factory = new ObjectFactory(configDirectory);111factory.initialize();112buildSpec = factory.getBuildSpec(buildSpecId);113if (buildSpec == null) {114throw new UMAException("Could not find " + buildSpecId + ".spec file.");115}116flagDefs = factory.getFlagDefinitions();117buildInfo = factory.getBuildInfo();118119macroMap.put("buildid", buildId);120macroMap.put("build_date", buildDate);121macroMap.put("vm_build_tag", buildTag);122macroMap.put("gc_build_tag", buildTag);123macroMap.put("jit_build_tag", getJITVersionTag(jitVersionFile, buildTag));124125this.excludeArtifacts = excludeArtifacts.split(",");126127processProperties(configPath);128129/*130* define phases from properties131*/132String phases = macroMap.get("phase_list");133if (phases == null) {134throw new UMAException("phase_list is not defined in makelib/uma.properties.");135}136phaseList = phases.split(" ");137138/*139* Verify that we have a mapping from JCL name to JCL artifact name140*/141for (String jcl : buildInfo.getJCLs()) {142if (macroMap.get(jcl) == null) {143throw new UMAException("Error: JCL [" + jcl + "] does not contain a mapping to it's artifact name in makelib/uma.properties.");144}145}146147dumpFlags();148} catch (OMObjectException e) {149throw new UMAException(e);150} catch (InvalidConfigurationException e) {151throw new UMAException(e);152}153}154155void processProperties(String path) throws UMAException {156try {157Properties properties = new Properties();158// Path is assumed to be in the shape {root}/buildspecs159properties.load(new FileInputStream(path + "/../makelib/uma.properties"));160for (Object key : properties.keySet()) {161String property = properties.getProperty((String) key);162macroMap.put((String) key, property);163}164} catch (FileNotFoundException e) {165// No uma.properties file, no problem.166Logger.getLogger().println(Logger.WarningLog, "Warning: uma.properties file not found.");167} catch (IOException e) {168throw new UMAException(e);169}170}171172public String getMetadataFilename() {173return "module.xml";174}175176public String getConfigurationName() {177return buildSpec.getId();178}179180public boolean isValidJcl(String jcl) {181for (String validJcl : buildInfo.getJCLs()) {182if (jcl.equals(validJcl)) {183return true;184}185}186return false;187}188189public String getDefaultJcl() {190return buildSpec.getDefaultJCL().getId();191}192193public Map<String, Flag> getFlags() {194return buildSpec.getFlags();195}196197public BuildSpec getBuildSpec() {198return buildSpec;199}200201private void dumpFlags() {202for (String flagId : buildSpec.getFlags().keySet()) {203if (isFlagSet(flagId)) {204Logger.getLogger().println(Logger.InformationL2Log, "flag: " + flagId + " is on");205} else {206Logger.getLogger().println(Logger.InformationL2Log, "flag: " + flagId + " is off");207}208}209}210211// TODO note this is a big hack until we can convert module.xmls to use this new version of the flags.212String transformFlag(String oldFlag) {213if (!oldFlag.startsWith("J9VM_")) {214return oldFlag;215}216217// hack some special cases in218if (oldFlag.equals("J9VM_ENV_BUILD_SHARED_LIB_VM")) {219return "env_buildSharedLibVM";220}221if (oldFlag.equals("J9VM_ENV_BUILD_STATIC_VM")) {222return "env_buildStaticVM";223}224if (oldFlag.equals("J9VM_IVE_JXE_OERELOCATOR")) {225return "ive_jxeOERelocator";226}227228String newFlag = oldFlag.substring(5); // trim off the J9VM_229int pos = newFlag.indexOf("_") + 1;230String flag = newFlag.substring(0, pos).toLowerCase();231boolean makeUpper = false;232while (true) {233int last = pos;234pos = newFlag.indexOf("_", last);235if (pos < 0) {236if (last >= newFlag.length()) {237break;238}239pos = newFlag.length();240}241if (makeUpper) {242flag += newFlag.substring(last, ++last).toUpperCase();243} else {244makeUpper = true;245}246flag += newFlag.substring(last, pos).toLowerCase();247pos += 1;248}249return flag;250}251252public boolean isFlagValid(String flag) {253flag = transformFlag(flag);254if (flagDefs.getFlagDefinition(flag) == null) {255return false;256}257return true;258}259260public boolean isFlagSet(String flagId) {261flagId = transformFlag(flagId);262if (isFlagValid(flagId)) {263Flag flag = buildSpec.getFlags().get(flagId);264if (flag != null) {265return flag.getState();266}267}268return false;269}270271public Set<String> getAllFlags() {272return buildSpec.getFlags().keySet();273}274275public void defineMacro(String key, String macro) {276macroMap.put(key, macro);277}278279public String replaceMacro(String macro) {280Property property = buildSpec.getProperty(macro);281if (property == null) {282return macroMap.get(macro);283}284return property.getValue();285}286287public IPlatform getPlatform() throws UMAException {288String configurationName = buildSpec.getId();289if (platform == null) {290if (configurationName.startsWith("win")) {291platform = new PlatformWindows(this);292} else if (configurationName.startsWith("zos")) {293platform = new PlatformZOS(this);294} else if (configurationName.startsWith("aix")295|| configurationName.startsWith("linux")296|| configurationName.startsWith("ose")297|| configurationName.startsWith("qnx")) {298platform = new PlatformUnix(this);299} else if (configurationName.startsWith("osx")) {300platform = new PlatformOSX(this);301}302303}304if (platform == null) {305throw new UMAException("No platform for " + configurationName);306}307return platform;308}309310String rawCopyrightNotice;311312public String getRawCopyrightNotice() throws UMAException {313if (rawCopyrightNotice == null) {314GregorianCalendar calendar = new GregorianCalendar();315rawCopyrightNotice = "Copyright (c) 2000, " + calendar.get(Calendar.YEAR) + " IBM Corp. and others";316}317return rawCopyrightNotice;318}319320String makefileCopyrightNotice;321322public String getMakefileCopyrightNotice() throws UMAException {323if (makefileCopyrightNotice == null) {324String majorVersion = buildInfo.getMajorVersion();325String minorVersion = buildInfo.getMinorVersion();326if (majorVersion == null) {327majorVersion = "0";328}329if (minorVersion == null) {330minorVersion = "0";331}332makefileCopyrightNotice =333"#\n" +334"# " + getRawCopyrightNotice() + "\n" +335"#\n" +336"# This program and the accompanying materials are made available under\n" +337"# the terms of the Eclipse Public License 2.0 which accompanies this\n" +338"# distribution and is available at https://www.eclipse.org/legal/epl-2.0/\n" +339"# or the Apache License, Version 2.0 which accompanies this distribution and\n" +340"# is available at https://www.apache.org/licenses/LICENSE-2.0.\n" +341"#\n" +342"# This Source Code may also be made available under the following\n" +343"# Secondary Licenses when the conditions for such availability set\n" +344"# forth in the Eclipse Public License, v. 2.0 are satisfied: GNU\n" +345"# General Public License, version 2 with the GNU Classpath\n" +346"# Exception [1] and GNU General Public License, version 2 with the\n" +347"# OpenJDK Assembly Exception [2].\n" +348"#\n" +349"# [1] https://www.gnu.org/software/classpath/license.html\n" +350"# [2] http://openjdk.java.net/legal/assembly-exception.html\n" +351"#\n" +352"# 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-exception\n" +353"\n" +354"# File generated in stream: " + majorVersion + "." + minorVersion + "\n" +355"#\n" +356"# Autogenerated Code\n";357}358return makefileCopyrightNotice;359}360361String cCopyrightNotice;362363public String getcCopyrightNotice() throws UMAException {364if (cCopyrightNotice == null) {365cCopyrightNotice =366"/*\n" +367" * " + getRawCopyrightNotice() + "\n" +368" * This program and the accompanying materials are made available under\n" +369" * the terms of the Eclipse Public License 2.0 which accompanies this\n" +370" * distribution and is available at https://www.eclipse.org/legal/epl-2.0/\n" +371" * or the Apache License, Version 2.0 which accompanies this distribution and\n" +372" * is available at https://www.apache.org/licenses/LICENSE-2.0.\n" +373" *\n" +374" * This Source Code may also be made available under the following\n" +375" * Secondary Licenses when the conditions for such availability set\n" +376" * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU\n" +377" * General Public License, version 2 with the GNU Classpath\n" +378" * Exception [1] and GNU General Public License, version 2 with the\n" +379" * OpenJDK Assembly Exception [2].\n" +380" *\n" +381" * [1] https://www.gnu.org/software/classpath/license.html\n" +382" * [2] http://openjdk.java.net/legal/assembly-exception.html\n" +383" *\n" +384" * 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-exception\n" +385" */\n";386}387return cCopyrightNotice;388}389390public boolean evaluateSinglePredicate(String predicate) throws UMAException {391if (predicate.startsWith("spec.")) {392if (predicate.startsWith("flags.", "spec.".length())) {393String flag = predicate.substring("spec.flags.".length());394if (!isFlagValid(flag)) {395throw new UMAException("Error: Invalid flag used: " + predicate);396}397return isFlagSet(flag);398} else if (predicate.startsWith("java", "spec.".length())) {399// spec.javaNN -> JAVA_SPEC_VERSION >= NN400String testVersion = predicate.substring("spec.java".length());401int testVersionVal;402403try {404testVersionVal = Integer.parseInt(testVersion);405} catch (NumberFormatException e) {406throw new UMAException("Error: Non-numeric spec.java: " + testVersion);407}408409String specVersion = macroMap.get("JAVA_SPEC_VERSION");410int specVersionVal;411412if (specVersion == null) {413throw new UMAException("Error: JAVA_SPEC_VERSION is not defined");414}415416try {417specVersionVal = Integer.parseInt(specVersion);418} catch (NumberFormatException e) {419throw new UMAException("Error: Non-numeric JAVA_SPEC_VERSION: " + specVersion);420}421422return specVersionVal >= testVersionVal;423} else if (predicate.startsWith("jcl.", "spec.".length())) {424String defaultJcl = predicate.substring("spec.jcl.".length());425if (!isValidJcl(defaultJcl)) {426throw new UMAException("Error: Invalid flag used: " + predicate);427}428429return defaultJcl.matches(getDefaultJcl());430} else {431// must be a platform identifier432String name = getConfigurationName();433String spec = predicate.substring("spec.".length());434return spec.equalsIgnoreCase(name) || name.matches(spec);435}436}437438throw new UMAException("Error: Unknown predicate condition " + predicate);439}440441public TemplateModel getDataModelExtension(String prefixTag, String extensionTag) throws UMAException {442if (prefixTag.equals(com.ibm.uma.UMA.FREEMARKER_UMA)) {443if (extensionTag.equals("buildinfo")) {444return new com.ibm.j9.uma.configuration.freemarker.BuildInfo(this);445}446} else if (prefixTag.startsWith("uma.spec.flags.")) {447return new com.ibm.j9.uma.configuration.freemarker.Flag(prefixTag.substring("uma.spec.flags.".length()), extensionTag, this);448} else if (prefixTag.equals("uma.spec")) {449if (extensionTag.equalsIgnoreCase("owners")) {450return new SimpleSequence(buildSpec.getOwnerIds());451} else if (extensionTag.equalsIgnoreCase("features")) {452return new Features(this);453} else if (extensionTag.equalsIgnoreCase("source")) {454return new Source(this);455}456return new com.ibm.j9.uma.configuration.freemarker.SimpleSpec(extensionTag, this);457}458return null;459}460461public TemplateModelIterator getPropertiesIterator() throws UMAException {462return new com.ibm.j9.uma.configuration.freemarker.PropertiesIterator(this);463}464465protected String getJITVersionTag(String jitVersionFileName, String buildTag) {466/* Looking to parse out the version from a line that looks like:467* #define TR_LEVEL_NAME "dev_20130104_30951"468* */469Pattern pattern = Pattern.compile("#define TR_LEVEL_NAME \"(.*)\"");470471String jitVersionString = "jitVersionCouldNotBeParsed";472if (jitVersionFileName.equals("")) {473System.out.print("jitVersionFile not set. Proceeding as a developer build.\n");474jitVersionString = buildTag;475} else {476try {477File jitVersionFile = new File(jitVersionFileName);478BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(jitVersionFile)));479String line = reader.readLine();480while (line != null) {481Matcher matcher = pattern.matcher(line);482if (matcher.matches()) {483jitVersionString = matcher.group(1);484break;485}486line = reader.readLine();487}488reader.close();489} catch (FileNotFoundException e) {490jitVersionString = "jitVersionFileNotFound";491System.out.println("jitVersionFileNotFound: " + jitVersionFileName);492System.exit(-1);493} catch (IOException e) {494jitVersionString = "jitVersionFileReadError";495System.out.println("jitVersionFileReadError: " + jitVersionFileName);496System.exit(-1);497}498}499return jitVersionString;500}501502public List<String> getExcludedArtifacts() {503Vector<String> listOfExcludeArtifacts = new Vector<String>();504505for (String excludeArtifact : excludeArtifacts) {506listOfExcludeArtifacts.add(excludeArtifact);507}508return listOfExcludeArtifacts;509}510511public String getAdditionalIncludesForArtifact(Artifact artifact) throws UMAException {512if ((buildInfo.getMinorVersion().equalsIgnoreCase("4") || buildInfo.getMinorVersion().equalsIgnoreCase("6"))513&& buildInfo.getMajorVersion().equalsIgnoreCase("2")) {514return "$(UMA_PATH_TO_ROOT)include $(UMA_PATH_TO_ROOT)oti ";515}516return "";517}518519public void verify() throws UMAException {520try {521buildSpec.verify(flagDefs, buildInfo);522} catch (InvalidBuildSpecException e) {523throw new UMAException(e);524}525}526527}528529530