1/* 2 * Copyright (c) 2016, 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 26package com.sun.codemodel.internal; 27 28// Based on modules grammar from http://openjdk.java.net/projects/jigsaw/doc/lang-vm.html 29 30import java.io.BufferedWriter; 31import java.io.IOException; 32import java.io.PrintWriter; 33import java.io.Writer; 34import java.util.Collection; 35import java.util.HashSet; 36import java.util.Iterator; 37import java.util.Set; 38 39/** 40 * Represents a Java module. 41 * @author Tomas Kraus 42 */ 43public class JModule { 44 45 /** Java module file name. */ 46 private static final String FILE_NAME = "module-info.java"; 47 48 /** Name of this module. Mandatory value. Shall not be {@code null}. */ 49 private final String name; 50 51 /** {@link Set} of Java module directives. */ 52 private final Set<JModuleDirective> directives; 53 54 /** 55 * Creates an instance of Java module. 56 * @param name Java module name. Value can not be {@code null} 57 * @param version Java module version. 58 */ 59 JModule(final String name) { 60 if (name == null) { 61 throw new IllegalArgumentException("Value of name is null"); 62 } 63 this.name = name; 64 this.directives = new HashSet<>(); 65 } 66 67 /** 68 * Gets the name of this module. 69 * @return name of this module. 70 */ 71 public String name() { 72 return name; 73 } 74 75 /** 76 * Gets module directives set. 77 * jUnit helper method. 78 * @return Module directives set. 79 */ 80 Set<JModuleDirective> getDirectives() { 81 return directives; 82 } 83 84 /** 85 * Adds a package to the list of Java module exports. 86 * The package name shall not be {@code null} or empty {@code String}. 87 * @param pkg Java package to be exported. 88 */ 89 public void _exports(final JPackage pkg) { 90 directives.add(new JExportsDirective(pkg.name())); 91 } 92 93 /** 94 * Adds packages to the list of Java module exports. 95 * @param pkgs Collection of packages to be added. 96 * @param addEmpty Adds also packages without any classes when {@code true}. 97 */ 98 public void _exports(final Collection<JPackage> pkgs, final boolean addEmpty) { 99 for (Iterator<JPackage> i = pkgs.iterator(); i.hasNext();) { 100 final JPackage pkg = i.next(); 101 if (addEmpty || pkg.hasClasses()) { 102 _exports(pkg); 103 } 104 } 105 } 106 107 /** 108 * Adds a module to the list of Java module requirements. 109 * The module name shall not be {@code null} or empty {@code String}. 110 * @param name Name of required Java module. 111 * @param isPublic Use {@code public} modifier. 112 * @param isStatic Use {@code static} modifier. 113 */ 114 public void _requires(final String name, final boolean isPublic, final boolean isStatic) { 115 directives.add(new JRequiresDirective(name, isPublic, isStatic)); 116 } 117 118 /** 119 * Adds a module to the list of Java module requirements without {@code public} and {@code static} modifiers. 120 * The module name shall not be {@code null} or empty {@code String}. 121 * @param name Name of required Java module. 122 */ 123 public void _requires(final String name) { 124 directives.add(new JRequiresDirective(name, false, false)); 125 } 126 127 /** 128 * Adds all modules to the list of Java module requirements. 129 * The module name shall not be {@code null} or empty {@code String}. 130 * @param names Names of required Java module. 131 * @param isPublic Use {@code public} modifier. 132 * @param isStatic Use {@code static} modifier. 133 */ 134 public void _requires(final boolean isPublic, final boolean isStatic, final String ...names) { 135 if (names != null) { 136 for (final String reqName : names) { 137 _requires(reqName, isPublic, isStatic); 138 } 139 } 140 } 141 142 /** 143 * Adds all modules to the list of Java module requirements without {@code public} and {@code static} modifiers. 144 * @param names Names of required Java module. 145 */ 146 public void _requires(final String ...names) { 147 _requires(false, false, names); 148 } 149 150 /** 151 * Print source code of Java Module declaration. 152 * @param f Java code formatter. 153 * @return provided instance of Java code formatter. 154 */ 155 public JFormatter generate(final JFormatter f) { 156 f.p("module").p(name); 157 f.p('{').nl(); 158 if (!directives.isEmpty()) { 159 f.i(); 160 for (final JModuleDirective directive : directives) { 161 directive.generate(f); 162 } 163 f.o(); 164 } 165 f.p('}').nl(); 166 return f; 167 } 168 169 /** 170 * Create {@code module-info.java} source writer. 171 * @return New instance of {@code module-info.java} source writer. 172 */ 173 private JFormatter createModuleInfoSourceFileWriter(final CodeWriter src) throws IOException { 174 Writer bw = new BufferedWriter(src.openSource(null, FILE_NAME)); 175 return new JFormatter(new PrintWriter(bw)); 176 } 177 178 /** 179 * Build {@code module-info.java} source file. 180 * @param src Source code writer. 181 * @throws IOException if there is any problem with writing the file. 182 */ 183 void build(final CodeWriter src) throws IOException { 184 final JFormatter f = createModuleInfoSourceFileWriter(src); 185 generate(f); 186 f.close(); 187 } 188 189} 190