/* * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang.reflect; import java.lang.annotation.Annotation; import java.lang.annotation.AnnotationFormatError; import java.lang.annotation.RetentionPolicy; import java.lang.module.ModuleClassLoader; import java.lang.module.ModuleId; import java.lang.module.ModuleInfo; import java.lang.module.ModuleNotPresentException; import java.lang.module.Version; import java.security.CodeSource; import java.util.Map; import java.util.LinkedHashMap; import sun.reflect.annotation.AnnotationType; import org.openjdk.jigsaw.Loader; public final class Module implements AnnotatedElement { private ModuleInfo moduleInfo; private ModuleClassLoader loader; private final CodeSource codeSource; /** * Package-private constructor used by ReflectAccess to enable * instantiation of these objects in Java code from the java.lang * package via sun.reflect.LangReflectAccess. */ Module(ModuleInfo mi, ModuleClassLoader ld, CodeSource cs) { loader = ld; moduleInfo = mi; codeSource = cs; } public ModuleClassLoader getClassLoader() { return loader; } public ModuleInfo getModuleInfo() { return moduleInfo; } public CodeSource getCodeSource() { return codeSource; } // Convenience methods public ModuleId getModuleId() { return moduleInfo.id(); } public String getName() { return moduleInfo.id().name(); } public Version getVersion() { return moduleInfo.id().version(); } // -- AnnotatedElement methods -- /** * {@inheritDoc} */ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return getAnnotation(annotationClass) != null; } /** * {@inheritDoc} */ public <A extends Annotation> A getAnnotation(Class<A> annotationClass) { if (annotationClass == null) throw new NullPointerException(); return (A) annotationsMap().get(annotationClass); } /** * {@inheritDoc} */ public Annotation[] getAnnotations() { // no inherited annotations return getDeclaredAnnotations(); } /** * {@inheritDoc} */ public Annotation[] getDeclaredAnnotations() { return annotationsMap.values().toArray(new Annotation[0]); } private transient Map<Class<? extends Annotation>, Annotation> annotationsMap; // Returns the cached annotations private synchronized Map<Class<? extends Annotation>, Annotation> annotationsMap() { if (annotationsMap != null) return annotationsMap; // module-info.class is not loaded in the VM as a Class object // we can't use sun.reflect.annotation.AnnotationParser here annotationsMap = new LinkedHashMap<Class<? extends Annotation>, Annotation>(); for (Annotation a: sun.misc.SharedSecrets. getJavaLangModuleAccess().getAnnotations(moduleInfo, this)) { Class<? extends Annotation> klass = a.annotationType(); AnnotationType type = AnnotationType.getInstance(klass); if (type.retention() == RetentionPolicy.RUNTIME) { if (annotationsMap.put(klass, a) != null) { throw new AnnotationFormatError( "Duplicate annotation for class: "+klass+": " + a); } } } return annotationsMap; } // ## EHS @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getName()); sb.append("(").append(moduleInfo.id()).append(")"); return sb.toString(); } /** * Tests if a module of the given module name * has been resolved and linked with this module's context. * * @param mn a module's name * @return true if the module of the given name is present; * false otherwise. */ public boolean isModulePresent(String mn) { return ((Loader)loader).isModulePresent(mn); } /** * Checks if a module of the given module name * has been resolved and linked with this module's context. * * @param mn a module's name * @throws ModuleNotPresentException if the module of the given name * is not present in this module's context. */ public void requireModulePresent(String mn) { if (!isModulePresent(mn)) { throw new ModuleNotPresentException("module " + mn + " not present"); } } }