1 /*
   2  * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.lang.model.element;
  27 
  28 import java.util.List;
  29 
  30 /**
  31  * Represents a module program element.  Provides access to
  32  * information about the module, its directives, and its members.
  33  *
  34  * @see javax.lang.model.util.Elements#getModuleOf
  35  * @since 9
  36  * @jls 7.7 Module Declarations
  37  * @spec JPMS
  38  */
  39 public interface ModuleElement extends Element, QualifiedNameable {
  40 
  41     /**
  42      * Returns the fully qualified name of this module.  For an
  43      * {@linkplain #isUnnamed() unnamed module}, an empty name is returned.
  44      *
  45      * @return the fully qualified name of this module, or an
  46      * empty name if this is an unnamed module
  47      */
  48     @Override
  49     Name getQualifiedName();
  50 
  51     /**
  52      * Returns the simple name of this module.  For an {@linkplain
  53      * #isUnnamed() unnamed module}, an empty name is returned.
  54      *
  55      * @return the simple name of this module or an empty name if
  56      * this is an unnamed module
  57      */
  58     @Override
  59     Name getSimpleName();
  60 
  61     /**
  62      * Returns the packages within this module.
  63      * @return the packages within this module
  64      */
  65     @Override
  66     List<? extends Element> getEnclosedElements();
  67 
  68     /**
  69      * Returns {@code true} if this is an open module and {@code
  70      * false} otherwise.
  71      *
  72      * @return {@code true} if this is an open module and {@code
  73      * false} otherwise
  74      */ // TODO: add @jls to unnamed module section
  75     boolean isOpen();
  76 
  77     /**
  78      * Returns {@code true} if this is an unnamed module and {@code
  79      * false} otherwise.
  80      *
  81      * @return {@code true} if this is an unnamed module and {@code
  82      * false} otherwise
  83      */ // TODO: add @jls to unnamed module section
  84     boolean isUnnamed();
  85 
  86     /**
  87      * Returns {@code null} since a module is not enclosed by another
  88      * element.
  89      *
  90      * @return {@code null}
  91      */
  92     @Override
  93     Element getEnclosingElement();
  94 
  95     /**
  96      * Returns the directives contained in the declaration of this module.
  97      * @return  the directives in the declaration of this module
  98      */
  99     List<? extends Directive> getDirectives();
 100 
 101     /**
 102      * The {@code kind} of a directive.
 103      *
 104      * <p>Note that it is possible additional directive kinds will be added
 105      * to accommodate new, currently unknown, language structures added to
 106      * future versions of the Java&trade; programming language.
 107      *
 108      * @since 9
 109      * @spec JPMS
 110      */
 111     enum DirectiveKind {
 112         /** A "requires (static|transitive)* module-name" directive. */
 113         REQUIRES,
 114         /** An "exports package-name [to module-name-list]" directive. */
 115         EXPORTS,
 116         /** An "opens package-name [to module-name-list]" directive. */
 117         OPENS,
 118         /** A "uses service-name" directive. */
 119         USES,
 120         /** A "provides service-name with implementation-name" directive. */
 121         PROVIDES
 122     };
 123 
 124     /**
 125      * Represents a directive within the declaration of this
 126      * module. The directives of a module declaration configure the
 127      * module in the Java Platform Module System.
 128      *
 129      * @since 9
 130      * @spec JPMS
 131      */
 132     interface Directive {
 133         /**
 134          * Returns the {@code kind} of this directive.
 135          *
 136          * @return the kind of this directive
 137          */
 138         DirectiveKind getKind();
 139 
 140         /**
 141          * Applies a visitor to this directive.
 142          *
 143          * @param <R> the return type of the visitor's methods
 144          * @param <P> the type of the additional parameter to the visitor's methods
 145          * @param v   the visitor operating on this directive
 146          * @param p   additional parameter to the visitor
 147          * @return a visitor-specified result
 148          */
 149         <R, P> R accept(DirectiveVisitor<R, P> v, P p);
 150     }
 151 
 152     /**
 153      * A visitor of module directives, in the style of the visitor design
 154      * pattern.  Classes implementing this interface are used to operate
 155      * on a directive when the kind of directive is unknown at compile time.
 156      * When a visitor is passed to a directive's {@link Directive#accept
 157      * accept} method, the <code>visit<i>Xyz</i></code> method applicable
 158      * to that directive is invoked.
 159      *
 160      * <p> Classes implementing this interface may or may not throw a
 161      * {@code NullPointerException} if the additional parameter {@code p}
 162      * is {@code null}; see documentation of the implementing class for
 163      * details.
 164      *
 165      * <p> <b>WARNING:</b> It is possible that methods will be added to
 166      * this interface to accommodate new, currently unknown, language
 167      * structures added to future versions of the Java&trade; programming
 168      * language. Methods to accommodate new language constructs will
 169      * be added in a source <em>compatible</em> way using
 170      * <em>default methods</em>.
 171      *
 172      * @param <R> the return type of this visitor's methods.  Use {@link
 173      *            Void} for visitors that do not need to return results.
 174      * @param <P> the type of the additional parameter to this visitor's
 175      *            methods.  Use {@code Void} for visitors that do not need an
 176      *            additional parameter.
 177      *
 178      * @since 9
 179      * @spec JPMS
 180      */
 181     interface DirectiveVisitor<R, P> {
 182         /**
 183          * Visits any directive as if by passing itself to that
 184          * directive's {@link Directive#accept accept} method and passing
 185          * {@code null} for the additional parameter.
 186          * The invocation {@code v.visit(d)} is equivalent to
 187          * {@code d.accept(v, null)}.
 188          * @param d  the directive to visit
 189          * @return a visitor-specified result
 190          * @implSpec This implementation is {@code visit(d, null)}
 191          */
 192         default R visit(Directive d) {
 193             return d.accept(this, null);
 194         }
 195 
 196         /**
 197          * Visits any directive as if by passing itself to that
 198          * directive's {@link Directive#accept accept} method.
 199          * The invocation {@code v.visit(d, p)} is equivalent to
 200          * {@code d.accept(v, p)}.
 201          * @param d  the directive to visit
 202          * @param p  a visitor-specified parameter
 203          * @return a visitor-specified result
 204          */
 205         default R visit(Directive d, P p) {
 206             return d.accept(this, p);
 207         }
 208 
 209         /**
 210          * Visits a {@code requires} directive.
 211          * @param d  the directive to visit
 212          * @param p  a visitor-specified parameter
 213          * @return a visitor-specified result
 214          */
 215         R visitRequires(RequiresDirective d, P p);
 216 
 217         /**
 218          * Visits an {@code exports} directive.
 219          * @param d  the directive to visit
 220          * @param p  a visitor-specified parameter
 221          * @return a visitor-specified result
 222          */
 223         R visitExports(ExportsDirective d, P p);
 224 
 225         /**
 226          * Visits an {@code opens} directive.
 227          * @param d  the directive to visit
 228          * @param p  a visitor-specified parameter
 229          * @return a visitor-specified result
 230          */
 231         R visitOpens(OpensDirective d, P p);
 232 
 233         /**
 234          * Visits a {@code uses} directive.
 235          * @param d  the directive to visit
 236          * @param p  a visitor-specified parameter
 237          * @return a visitor-specified result
 238          */
 239         R visitUses(UsesDirective d, P p);
 240 
 241         /**
 242          * Visits a {@code provides} directive.
 243          * @param d  the directive to visit
 244          * @param p  a visitor-specified parameter
 245          * @return a visitor-specified result
 246          */
 247         R visitProvides(ProvidesDirective d, P p);
 248 
 249         /**
 250          * Visits an unknown directive.
 251          * This can occur if the language evolves and new kinds of directive are added.
 252          * @param d  the directive to visit
 253          * @param p  a visitor-specified parameter
 254          * @return a visitor-specified result
 255          * @throws UnknownDirectiveException a visitor implementation may optionally throw this exception
 256          * @implSpec This implementation throws {@code new UnknownDirectiveException(d, p)}.
 257          */
 258         default R visitUnknown(Directive d, P p) {
 259             throw new UnknownDirectiveException(d, p);
 260         }
 261     }
 262 
 263     /**
 264      * A dependency of a module.
 265      * @since 9
 266      * @spec JPMS
 267      */
 268     interface RequiresDirective extends Directive {
 269         /**
 270          * Returns whether or not this is a static dependency.
 271          * @return whether or not this is a static dependency
 272          */
 273         boolean isStatic();
 274 
 275         /**
 276          * Returns whether or not this is a transitive dependency.
 277          * @return whether or not this is a transitive dependency
 278          */
 279         boolean isTransitive();
 280 
 281         /**
 282          * Returns the module that is required
 283          * @return the module that is required
 284          */
 285         ModuleElement getDependency();
 286     }
 287 
 288     /**
 289      * An exported package of a module.
 290      * @since 9
 291      * @spec JPMS
 292      */
 293     interface ExportsDirective extends Directive {
 294 
 295         /**
 296          * Returns the package being exported.
 297          * @return the package being exported
 298          */
 299         PackageElement getPackage();
 300 
 301         /**
 302          * Returns the specific modules to which the package is being exported,
 303          * or null, if the package is exported to all modules which
 304          * have readability to this module.
 305          * @return the specific modules to which the package is being exported
 306          */
 307         List<? extends ModuleElement> getTargetModules();
 308     }
 309 
 310     /**
 311      * An opened package of a module.
 312      * @since 9
 313      * @spec JPMS
 314      */
 315     interface OpensDirective extends Directive {
 316 
 317         /**
 318          * Returns the package being opened.
 319          * @return the package being opened
 320          */
 321         PackageElement getPackage();
 322 
 323         /**
 324          * Returns the specific modules to which the package is being open
 325          * or null, if the package is open all modules which
 326          * have readability to this module.
 327          * @return the specific modules to which the package is being opened
 328          */
 329         List<? extends ModuleElement> getTargetModules();
 330     }
 331 
 332     /**
 333      * An implementation of a service provided by a module.
 334      * @since 9
 335      * @spec JPMS
 336      */
 337     interface ProvidesDirective extends Directive {
 338         /**
 339          * Returns the service being provided.
 340          * @return the service being provided
 341          */
 342         TypeElement getService();
 343 
 344         /**
 345          * Returns the implementations of the service being provided.
 346          * @return the implementations of the service being provided
 347          */
 348         List<? extends TypeElement> getImplementations();
 349     }
 350 
 351     /**
 352      * A reference to a service used by a module.
 353      * @since 9
 354      * @spec JPMS
 355      */
 356     interface UsesDirective extends Directive {
 357         /**
 358          * Returns the service that is used.
 359          * @return the service that is used
 360          */
 361         TypeElement getService();
 362     }
 363 }