Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/rmi/rmic/BatchEnvironment.java
38831 views
/*1* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*****************************************************************************/26/* Copyright (c) IBM Corporation 1998 */27/* */28/* (C) Copyright IBM Corp. 1998 */29/* */30/*****************************************************************************/3132package sun.rmi.rmic;3334import java.io.File;35import java.io.IOException;36import java.io.OutputStream;37import java.util.Collection;38import java.util.Enumeration;39import java.util.Iterator;40import java.util.LinkedHashSet;41import java.util.StringTokenizer;42import java.util.Vector;43import java.util.jar.JarFile;44import java.util.jar.Manifest;45import java.util.jar.Attributes;46import sun.tools.java.ClassPath;4748/**49* BatchEnvironment for rmic extends javac's version in four ways:50* 1. It overrides errorString() to handle looking for rmic-specific51* error messages in rmic's resource bundle52* 2. It provides a mechanism for recording intermediate generated53* files so that they can be deleted later.54* 3. It holds a reference to the Main instance so that generators55* can refer to it.56* 4. It provides access to the ClassPath passed to the constructor.57*58* WARNING: The contents of this source file are not part of any59* supported API. Code that depends on them does so at its own risk:60* they are subject to change or removal without notice.61*/6263public class BatchEnvironment extends sun.tools.javac.BatchEnvironment {6465/** instance of Main which created this environment */66private Main main;6768/**69* Create a ClassPath object for rmic from a class path string.70*/71public static ClassPath createClassPath(String classPathString) {72ClassPath[] paths = classPaths(null, classPathString, null, null);73return paths[1];74}7576/**77* Create a ClassPath object for rmic from the relevant command line78* options for class path, boot class path, and extension directories.79*/80public static ClassPath createClassPath(String classPathString,81String sysClassPathString,82String extDirsString)83{84/**85* Previously, this method delegated to the86* sun.tools.javac.BatchEnvironment.classPaths method in order87* to supply default values for paths not specified on the88* command line, expand extensions directories into specific89* JAR files, and construct the ClassPath object-- but as part90* of the fix for 6473331, which adds support for Class-Path91* manifest entries in JAR files, those steps are now handled92* here directly, with the help of a Path utility class copied93* from the new javac implementation (see below).94*/95Path path = new Path();9697if (sysClassPathString == null) {98sysClassPathString = System.getProperty("sun.boot.class.path");99}100if (sysClassPathString != null) {101path.addFiles(sysClassPathString);102}103104/*105* Class-Path manifest entries are supported for JAR files106* everywhere except in the boot class path.107*/108path.expandJarClassPaths(true);109110if (extDirsString == null) {111extDirsString = System.getProperty("java.ext.dirs");112}113if (extDirsString != null) {114path.addDirectories(extDirsString);115}116117/*118* In the application class path, an empty element means119* the current working directory.120*/121path.emptyPathDefault(".");122123if (classPathString == null) {124// The env.class.path property is the user's CLASSPATH125// environment variable, and it set by the wrapper (ie,126// javac.exe).127classPathString = System.getProperty("env.class.path");128if (classPathString == null) {129classPathString = ".";130}131}132path.addFiles(classPathString);133134return new ClassPath(path.toArray(new String[path.size()]));135}136137/**138* Create a BatchEnvironment for rmic with the given class path,139* stream for messages and Main.140*/141public BatchEnvironment(OutputStream out, ClassPath path, Main main) {142super(out, new ClassPath(""), path);143// use empty "sourcePath" (see 4666958)144this.main = main;145}146147/**148* Get the instance of Main which created this environment.149*/150public Main getMain() {151return main;152}153154/**155* Get the ClassPath.156*/157public ClassPath getClassPath() {158return binaryPath;159}160161/** list of generated source files created in this environment */162private Vector<File> generatedFiles = new Vector<>();163164/**165* Remember a generated source file generated so that it166* can be removed later, if appropriate.167*/168public void addGeneratedFile(File file) {169generatedFiles.addElement(file);170}171172/**173* Delete all the generated source files made during the execution174* of this environment (those that have been registered with the175* "addGeneratedFile" method).176*/177public void deleteGeneratedFiles() {178synchronized(generatedFiles) {179Enumeration<File> enumeration = generatedFiles.elements();180while (enumeration.hasMoreElements()) {181File file = enumeration.nextElement();182file.delete();183}184generatedFiles.removeAllElements();185}186}187188/**189* Release resources, if any.190*/191public void shutdown() {192main = null;193generatedFiles = null;194super.shutdown();195}196197/**198* Return the formatted, localized string for a named error message199* and supplied arguments. For rmic error messages, with names that200* being with "rmic.", look up the error message in rmic's resource201* bundle; otherwise, defer to java's superclass method.202*/203public String errorString(String err,204Object arg0, Object arg1, Object arg2)205{206if (err.startsWith("rmic.") || err.startsWith("warn.rmic.")) {207String result = Main.getText(err,208(arg0 != null ? arg0.toString() : null),209(arg1 != null ? arg1.toString() : null),210(arg2 != null ? arg2.toString() : null));211212if (err.startsWith("warn.")) {213result = "warning: " + result;214}215return result;216} else {217return super.errorString(err, arg0, arg1, arg2);218}219}220public void reset() {221}222223/**224* Utility for building paths of directories and JAR files. This225* class was copied from com.sun.tools.javac.util.Paths as part of226* the fix for 6473331, which adds support for Class-Path manifest227* entries in JAR files. Diagnostic code is simply commented out228* because rmic silently ignored these conditions historically.229*/230private static class Path extends LinkedHashSet<String> {231private static final long serialVersionUID = 0;232private static final boolean warn = false;233234private static class PathIterator implements Collection<String> {235private int pos = 0;236private final String path;237private final String emptyPathDefault;238239public PathIterator(String path, String emptyPathDefault) {240this.path = path;241this.emptyPathDefault = emptyPathDefault;242}243public PathIterator(String path) { this(path, null); }244public Iterator<String> iterator() {245return new Iterator<String>() {246public boolean hasNext() {247return pos <= path.length();248}249public String next() {250int beg = pos;251int end = path.indexOf(File.pathSeparator, beg);252if (end == -1)253end = path.length();254pos = end + 1;255256if (beg == end && emptyPathDefault != null)257return emptyPathDefault;258else259return path.substring(beg, end);260}261public void remove() {262throw new UnsupportedOperationException();263}264};265}266267// required for Collection.268public int size() {269throw new UnsupportedOperationException();270}271public boolean isEmpty() {272throw new UnsupportedOperationException();273}274public boolean contains(Object o) {275throw new UnsupportedOperationException();276}277public Object[] toArray() {278throw new UnsupportedOperationException();279}280public <T> T[] toArray(T[] a) {281throw new UnsupportedOperationException();282}283public boolean add(String o) {284throw new UnsupportedOperationException();285}286public boolean remove(Object o) {287throw new UnsupportedOperationException();288}289public boolean containsAll(Collection<?> c) {290throw new UnsupportedOperationException();291}292public boolean addAll(Collection<? extends String> c) {293throw new UnsupportedOperationException();294}295public boolean removeAll(Collection<?> c) {296throw new UnsupportedOperationException();297}298public boolean retainAll(Collection<?> c) {299throw new UnsupportedOperationException();300}301public void clear() {302throw new UnsupportedOperationException();303}304public boolean equals(Object o) {305throw new UnsupportedOperationException();306}307public int hashCode() {308throw new UnsupportedOperationException();309}310}311312/** Is this the name of a zip file? */313private static boolean isZip(String name) {314return new File(name).isFile();315}316317private boolean expandJarClassPaths = false;318319public Path expandJarClassPaths(boolean x) {320expandJarClassPaths = x;321return this;322}323324/** What to use when path element is the empty string */325private String emptyPathDefault = null;326327public Path emptyPathDefault(String x) {328emptyPathDefault = x;329return this;330}331332public Path() { super(); }333334public Path addDirectories(String dirs, boolean warn) {335if (dirs != null)336for (String dir : new PathIterator(dirs))337addDirectory(dir, warn);338return this;339}340341public Path addDirectories(String dirs) {342return addDirectories(dirs, warn);343}344345private void addDirectory(String dir, boolean warn) {346if (! new File(dir).isDirectory()) {347// if (warn)348// log.warning(Position.NOPOS,349// "dir.path.element.not.found", dir);350return;351}352353for (String direntry : new File(dir).list()) {354String canonicalized = direntry.toLowerCase();355if (canonicalized.endsWith(".jar") ||356canonicalized.endsWith(".zip"))357addFile(dir + File.separator + direntry, warn);358}359}360361public Path addFiles(String files, boolean warn) {362if (files != null)363for (String file : new PathIterator(files, emptyPathDefault))364addFile(file, warn);365return this;366}367368public Path addFiles(String files) {369return addFiles(files, warn);370}371372private void addFile(String file, boolean warn) {373if (contains(file)) {374/* Discard duplicates and avoid infinite recursion */375return;376}377378File ele = new File(file);379if (! ele.exists()) {380/* No such file or directory exist */381if (warn)382// log.warning(Position.NOPOS,383// "path.element.not.found", file);384return;385}386387if (ele.isFile()) {388/* File is an ordinay file */389String arcname = file.toLowerCase();390if (! (arcname.endsWith(".zip") ||391arcname.endsWith(".jar"))) {392/* File name don't have right extension */393// if (warn)394// log.warning(Position.NOPOS,395// "invalid.archive.file", file);396return;397}398}399400/* Now what we have left is either a directory or a file name401confirming to archive naming convention */402403super.add(file);404if (expandJarClassPaths && isZip(file))405addJarClassPath(file, warn);406}407408// Adds referenced classpath elements from a jar's Class-Path409// Manifest entry. In some future release, we may want to410// update this code to recognize URLs rather than simple411// filenames, but if we do, we should redo all path-related code.412private void addJarClassPath(String jarFileName, boolean warn) {413try {414String jarParent = new File(jarFileName).getParent();415JarFile jar = new JarFile(jarFileName);416417try {418Manifest man = jar.getManifest();419if (man == null) return;420421Attributes attr = man.getMainAttributes();422if (attr == null) return;423424String path = attr.getValue(Attributes.Name.CLASS_PATH);425if (path == null) return;426427for (StringTokenizer st = new StringTokenizer(path);428st.hasMoreTokens();) {429String elt = st.nextToken();430if (jarParent != null)431elt = new File(jarParent, elt).getCanonicalPath();432addFile(elt, warn);433}434} finally {435jar.close();436}437} catch (IOException e) {438// log.error(Position.NOPOS,439// "error.reading.file", jarFileName,440// e.getLocalizedMessage());441}442}443}444}445446447