View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.start;
20  
21  import java.io.IOException;
22  import java.nio.file.Path;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.List;
26  
27  import org.eclipse.jetty.start.graph.Graph;
28  import org.eclipse.jetty.start.graph.GraphException;
29  import org.eclipse.jetty.start.graph.OnlyTransitivePredicate;
30  import org.eclipse.jetty.start.graph.Selection;
31  
32  /**
33   * Access for all modules declared, as well as what is enabled.
34   */
35  public class Modules extends Graph<Module>
36  {
37      private final BaseHome baseHome;
38      private final StartArgs args;
39  
40      public Modules(BaseHome basehome, StartArgs args)
41      {
42          this.baseHome = basehome;
43          this.args = args;
44          this.setSelectionTerm("enable");
45          this.setNodeTerm("module");
46          
47          String java_version = System.getProperty("java.version");
48          if (java_version!=null)
49          {
50              args.setProperty("java.version",java_version,"<internal>",false);
51          }        
52      }
53  
54      public void dump()
55      {
56          List<Module> ordered = new ArrayList<>();
57          ordered.addAll(getNodes());
58          Collections.sort(ordered,new Module.NameComparator());
59  
60          List<Module> active = getSelected();
61  
62          for (Module module : ordered)
63          {
64              boolean activated = active.contains(module);
65              boolean selected = module.isSelected();
66              boolean transitive = selected && module.matches(OnlyTransitivePredicate.INSTANCE);
67  
68              String status = "[ ]";
69              if (transitive)
70              {
71                  status = "[t]";
72              }
73              else if (selected)
74              {
75                  status = "[x]";
76              }
77  
78              System.out.printf("%n %s Module: %s%n",status,module.getName());
79              if (!module.getName().equals(module.getFilesystemRef()))
80              {
81                  System.out.printf("        Ref: %s%n",module.getFilesystemRef());
82              }
83              for (String parent : module.getParentNames())
84              {
85                  System.out.printf("     Depend: %s%n",parent);
86              }
87              for (String lib : module.getLibs())
88              {
89                  System.out.printf("        LIB: %s%n",lib);
90              }
91              for (String xml : module.getXmls())
92              {
93                  System.out.printf("        XML: %s%n",xml);
94              }
95              if (StartLog.isDebugEnabled())
96              {
97                  System.out.printf("      depth: %d%n",module.getDepth());
98              }
99              if (activated)
100             {
101                 for (Selection selection : module.getSelections())
102                 {
103                     System.out.printf("    Enabled: <via> %s%n",selection);
104                 }
105             }
106             else
107             {
108                 System.out.printf("    Enabled: <not enabled in this configuration>%n");
109             }
110         }
111     }
112 
113     @Override
114     public Module resolveNode(String name)
115     {
116         String expandedName = args.getProperties().expand(name);
117 
118         if (Props.hasPropertyKey(expandedName))
119         {
120             StartLog.debug("Not yet able to expand property in: %s",name);
121             return null;
122         }
123 
124         Path file = baseHome.getPath("modules/" + expandedName + ".mod");
125         if (FS.canReadFile(file))
126         {
127             Module parent = registerModule(file);
128             parent.expandProperties(args.getProperties());
129             updateParentReferencesTo(parent);
130             return parent;
131         }
132         else
133         {
134             if (!Props.hasPropertyKey(name))
135             {
136                 StartLog.debug("Missing module definition: [ Mod: %s | File: %s ]",name,file);
137             }
138             return null;
139         }
140     }
141     
142     @Override
143     public void onNodeSelected(Module module)
144     {
145         StartLog.debug("on node selected: [%s] (%s.mod)",module.getName(),module.getFilesystemRef());
146         args.parseModule(module);
147         module.expandProperties(args.getProperties());
148     }
149 
150     public List<String> normalizeLibs(List<Module> active)
151     {
152         List<String> libs = new ArrayList<>();
153         for (Module module : active)
154         {
155             for (String lib : module.getLibs())
156             {
157                 if (!libs.contains(lib))
158                 {
159                     libs.add(lib);
160                 }
161             }
162         }
163         return libs;
164     }
165 
166     public List<String> normalizeXmls(List<Module> active)
167     {
168         List<String> xmls = new ArrayList<>();
169         for (Module module : active)
170         {
171             for (String xml : module.getXmls())
172             {
173                 if (!xmls.contains(xml))
174                 {
175                     xmls.add(xml);
176                 }
177             }
178         }
179         return xmls;
180     }
181 
182     public void registerAll() throws IOException
183     {
184         for (Path path : baseHome.getPaths("modules/*.mod"))
185         {
186             registerModule(path);
187         }
188     }
189 
190     private Module registerModule(Path file)
191     {
192         if (!FS.canReadFile(file))
193         {
194             throw new GraphException("Cannot read file: " + file);
195         }
196         String shortName = baseHome.toShortForm(file);
197         try
198         {
199             StartLog.debug("Registering Module: %s",shortName);
200             Module module = new Module(baseHome,file);
201             return register(module);
202         }
203         catch (Throwable t)
204         {
205             throw new GraphException("Unable to register module: " + shortName,t);
206         }
207     }
208 
209     /**
210      * Modules can have a different logical name than to their filesystem reference. This updates existing references to
211      * the filesystem form to use the logical
212      * name form.
213      * 
214      * @param module
215      *            the module that might have other modules referring to it.
216      */
217     private void updateParentReferencesTo(Module module)
218     {
219         if (module.getName().equals(module.getFilesystemRef()))
220         {
221             // nothing to do, its sane already
222             return;
223         }
224 
225         for (Module m : getNodes())
226         {
227             List<String> resolvedParents = new ArrayList<>();
228             for (String parent : m.getParentNames())
229             {
230                 if (parent.equals(module.getFilesystemRef()))
231                 {
232                     // use logical name instead
233                     resolvedParents.add(module.getName());
234                 }
235                 else
236                 {
237                     // use name as-is
238                     resolvedParents.add(parent);
239                 }
240             }
241             m.setParentNames(resolvedParents);
242         }
243     }
244 
245     @Override
246     public String toString()
247     {
248         StringBuilder str = new StringBuilder();
249         str.append("Modules[");
250         str.append("count=").append(count());
251         str.append(",<");
252         boolean delim = false;
253         for (String name : getNodeNames())
254         {
255             if (delim)
256             {
257                 str.append(',');
258             }
259             str.append(name);
260             delim = true;
261         }
262         str.append(">");
263         str.append("]");
264         return str.toString();
265     }
266 
267 }