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.builders;
20  
21  import java.io.BufferedReader;
22  import java.io.BufferedWriter;
23  import java.io.IOException;
24  import java.io.PrintWriter;
25  import java.nio.charset.StandardCharsets;
26  import java.nio.file.Files;
27  import java.nio.file.Path;
28  import java.nio.file.StandardOpenOption;
29  import java.util.HashSet;
30  import java.util.List;
31  import java.util.Set;
32  
33  import org.eclipse.jetty.start.BaseBuilder;
34  import org.eclipse.jetty.start.BaseHome;
35  import org.eclipse.jetty.start.Module;
36  import org.eclipse.jetty.start.Props;
37  import org.eclipse.jetty.start.StartLog;
38  import org.eclipse.jetty.start.graph.OnlyTransitivePredicate;
39  
40  /**
41   * Management of the <code>${jetty.base}/start.ini</code> based configuration.
42   * <p>
43   * Implementation of the <code>--add-to-start=[name]</code> command line behavior
44   */
45  public class StartIniBuilder implements BaseBuilder.Config
46  {
47      private final BaseHome baseHome;
48      private final Path startIni;
49  
50      /* List of modules already present in start.ini */
51      private Set<String> modulesPresent = new HashSet<>();
52  
53      /* List of properties (keys only) already present in start.ini */
54      private Set<String> propsPresent = new HashSet<>();
55  
56      public StartIniBuilder(BaseBuilder baseBuilder) throws IOException
57      {
58          this.baseHome = baseBuilder.getBaseHome();
59          this.startIni = baseHome.getBasePath("start.ini");
60  
61          if (Files.exists(startIni))
62          {
63              parseIni();
64          }
65      }
66  
67      private void parseIni() throws IOException
68      {
69          try (BufferedReader reader = Files.newBufferedReader(startIni,StandardCharsets.UTF_8))
70          {
71              String line;
72              while ((line = reader.readLine()) != null)
73              {
74                  line = line.trim();
75                  if (line.startsWith("--module="))
76                  {
77                      List<String> moduleNames = Props.getValues(line);
78                      this.modulesPresent.addAll(moduleNames);
79                  }
80                  else if (!line.startsWith("-") && line.contains("="))
81                  {
82                      String key = line.substring(0,line.indexOf('='));
83                      this.propsPresent.add(key);
84                  }
85              }
86          }
87      }
88  
89      @Override
90      public boolean addModule(Module module) throws IOException
91      {
92          if (modulesPresent.contains(module.getName()))
93          {
94              StartLog.info("%-15s already initialised in %s",module.getName(),baseHome.toShortForm(startIni));
95              // skip, already present
96              return false;
97          }
98  
99          if (module.isDynamic())
100         {
101             if (module.hasIniTemplate())
102             {
103                 // warn
104                 StartLog.warn("%-15s not adding [ini-template] from dynamic module",module.getName());
105             }
106             return false;
107         }
108 
109         String mode = "";
110         boolean isTransitive = module.matches(OnlyTransitivePredicate.INSTANCE);
111         if (isTransitive)
112         {
113             mode = "(transitively) ";
114         }
115 
116         if (module.hasIniTemplate() || !isTransitive)
117         {
118             StartLog.info("%-15s initialised %sin %s",module.getName(),mode,baseHome.toShortForm(startIni));
119 
120             // Append to start.ini
121             try (BufferedWriter writer = Files.newBufferedWriter(startIni,StandardCharsets.UTF_8,StandardOpenOption.APPEND,StandardOpenOption.CREATE))
122             {
123                 writeModuleSection(writer,module);
124             }
125             return true;
126         }
127 
128         return false;
129     }
130 
131     protected void writeModuleSection(BufferedWriter writer, Module module)
132     {
133         PrintWriter out = new PrintWriter(writer);
134 
135         out.println("# --------------------------------------- ");
136         out.println("# Module: " + module.getName());
137         out.println("--module=" + module.getName());
138         out.println();
139 
140         for (String line : module.getIniTemplate())
141         {
142             out.println(line);
143         }
144 
145         out.println();
146         out.flush();
147     }
148 }