View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 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.config;
20  
21  import java.io.File;
22  import java.net.URI;
23  import java.net.URISyntaxException;
24  import java.net.URL;
25  import java.nio.file.Path;
26  import java.util.regex.Matcher;
27  import java.util.regex.Pattern;
28  
29  import org.eclipse.jetty.start.BaseHome;
30  import org.eclipse.jetty.start.FS;
31  import org.eclipse.jetty.start.Props;
32  import org.eclipse.jetty.start.Props.Prop;
33  import org.eclipse.jetty.start.RawArgs;
34  import org.eclipse.jetty.start.UsageException;
35  
36  /**
37   * Configuration Source representing the Command Line arguments.
38   */
39  public class CommandLineConfigSource implements ConfigSource
40  {
41      public static final String ORIGIN_INTERNAL_FALLBACK = "<internal-fallback>";
42      public static final String ORIGIN_CMD_LINE = "<command-line>";
43  
44      private final RawArgs args;
45      private final Props props;
46      private final Path homePath;
47      private final Path basePath;
48  
49      public CommandLineConfigSource(String rawargs[])
50      {
51          this.args = new RawArgs();
52          this.props = new Props();
53          for (String arg : rawargs)
54          {
55              this.args.addArg(arg,ORIGIN_CMD_LINE);
56              this.props.addPossibleProperty(arg,ORIGIN_CMD_LINE);
57          }
58  
59          // Setup ${jetty.base} and ${jetty.home}
60          this.homePath = findJettyHomePath().toAbsolutePath();
61          this.basePath = findJettyBasePath().toAbsolutePath();
62  
63          // Update System Properties
64          setSystemProperty(BaseHome.JETTY_HOME,homePath.toAbsolutePath().toString());
65          setSystemProperty(BaseHome.JETTY_BASE,basePath.toAbsolutePath().toString());
66      }
67  
68      private final Path findJettyBasePath()
69      {
70          // If a jetty property is defined, use it
71          Prop prop = this.props.getProp(BaseHome.JETTY_BASE,false);
72          if (prop != null && !isEmpty(prop.value))
73          {
74              return FS.toPath(prop.value);
75          }
76  
77          // If a system property is defined, use it
78          String val = System.getProperty(BaseHome.JETTY_BASE);
79          if (!isEmpty(val))
80          {
81              return FS.toPath(val);
82          }
83  
84          // Lastly, fall back to base == ${user.dir}
85          Path base = FS.toPath(this.props.getString("user.dir","."));
86          setProperty(BaseHome.JETTY_BASE,base.toString(),ORIGIN_INTERNAL_FALLBACK);
87          return base;
88      }
89  
90      private final Path findJettyHomePath()
91      {
92          // If a jetty property is defined, use it
93          Prop prop = this.props.getProp(BaseHome.JETTY_HOME,false);
94          if (prop != null && !isEmpty(prop.value))
95          {
96              return FS.toPath(prop.value);
97          }
98  
99          // If a system property is defined, use it
100         String val = System.getProperty(BaseHome.JETTY_HOME);
101         if (!isEmpty(val))
102         {
103             return FS.toPath(val);
104         }
105 
106         // Attempt to find path relative to content in jetty's start.jar
107         // based on lookup for the Main class (from jetty's start.jar)
108         String classRef = "org/eclipse/jetty/start/Main.class";
109         URL jarfile = this.getClass().getClassLoader().getResource(classRef);
110         if (jarfile != null)
111         {
112             Matcher m = Pattern.compile("jar:(file:.*)!/" + classRef).matcher(jarfile.toString());
113             if (m.matches())
114             {
115                 // ${jetty.home} is relative to found BaseHome class
116                 try
117                 {
118                     return new File(new URI(m.group(1))).getParentFile().toPath();
119                 }
120                 catch (URISyntaxException e)
121                 {
122                     throw new UsageException(UsageException.ERR_UNKNOWN,e);
123                 }
124             }
125         }
126 
127         // Lastly, fall back to ${user.dir} default
128         Path home = FS.toPath(System.getProperty("user.dir","."));
129         setProperty(BaseHome.JETTY_HOME,home.toString(),ORIGIN_INTERNAL_FALLBACK);
130         return home;
131     }
132 
133     private boolean isEmpty(String value)
134     {
135         if (value == null)
136         {
137             return true;
138         }
139         int len = value.length();
140         for (int i = 0; i < len; i++)
141         {
142             int c = value.codePointAt(i);
143             if (!Character.isWhitespace(c))
144             {
145                 return false;
146             }
147         }
148         return true;
149     }
150 
151     @Override
152     public boolean equals(Object obj)
153     {
154         if (this == obj)
155         {
156             return true;
157         }
158         if (obj == null)
159         {
160             return false;
161         }
162         if (getClass() != obj.getClass())
163         {
164             return false;
165         }
166         CommandLineConfigSource other = (CommandLineConfigSource)obj;
167         if (args == null)
168         {
169             if (other.args != null)
170             {
171                 return false;
172             }
173         }
174         else if (!args.equals(other.args))
175         {
176             return false;
177         }
178         return true;
179     }
180 
181     @Override
182     public RawArgs getArgs()
183     {
184         return args;
185     }
186 
187     public Path getBasePath()
188     {
189         return basePath;
190     }
191 
192     public Path getHomePath()
193     {
194         return homePath;
195     }
196 
197     @Override
198     public String getId()
199     {
200         return ORIGIN_CMD_LINE;
201     }
202 
203     @Override
204     public String getProperty(String key)
205     {
206         return props.getString(key);
207     }
208 
209     @Override
210     public Props getProps()
211     {
212         return props;
213     }
214 
215     @Override
216     public int getWeight()
217     {
218         return -1; // default value for command line
219     }
220 
221     @Override
222     public int hashCode()
223     {
224         final int prime = 31;
225         int result = 1;
226         result = (prime * result) + ((args == null)?0:args.hashCode());
227         return result;
228     }
229 
230     public void setProperty(String key, String value, String origin)
231     {
232         this.props.setProperty(key,value,origin);
233     }
234 
235     public void setSystemProperty(String key, String value)
236     {
237         this.props.setSystemProperty(key,value);
238     }
239 
240     @Override
241     public String toString()
242     {
243         return String.format("%s[%s,args.length=%d]",this.getClass().getSimpleName(),getId(),getArgs().size());
244     }
245 }