1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.millscript.conf;
22
23 import org.millscript.commons.alert.Alert;
24 import org.millscript.commons.alert.EscapeException;
25 import org.millscript.commons.alert.reporters.StandardMishapAlertReporter;
26 import org.millscript.commons.alert.reporters.StandardWarningAlertReporter;
27 import org.millscript.commons.util.EMap;
28 import org.millscript.commons.util.map.EHashMap;
29 import org.millscript.commons.vfs.VFS;
30 import org.millscript.commons.vfs.VFile;
31 import org.millscript.commons.vfs.VFolder;
32 import org.millscript.millscript.URLSource;
33 import org.millscript.millscript.alert.Alerts;
34 import org.millscript.millscript.conf.logging.Logger;
35 import org.millscript.millscript.functions.BinaryFunction;
36 import org.millscript.millscript.functions.DateFieldFunction;
37 import org.millscript.millscript.loaders.LoaderBuilder;
38 import org.millscript.millscript.tools.CastLibrary;
39 import org.millscript.millscript.tools.CharacterEntity;
40 import org.millscript.millscript.tools.XMLCharacterEntity;
41 import org.millscript.millscript.vm.Engine;
42 import org.millscript.millscript.vm.Package;
43 import org.millscript.millscript.vm.StandardEngine;
44
45 import java.io.IOException;
46 import java.net.URL;
47 import java.nio.charset.Charset;
48 import java.util.Calendar;
49 import java.util.Enumeration;
50
51 /**
52 * This class is a starting point for implementing a configuration object. You
53 * will still need to implement several methods, but basic properties and print
54 * methods are handled.
55 */
56 public abstract class AbstractConfiguration implements Configuration {
57
58 /**
59 * Holds the VFS for this configuration.
60 */
61 protected final VFS vfs = new VFS();
62
63 /**
64 * The current working direcotry.
65 */
66 protected final VFolder cwd = vfs.getCurrentWorkingFolder();
67
68 /**
69 * Holds the HTML character entities configuration.
70 */
71 protected final CharacterEntity htmlCharacterEntities = new CharacterEntity();
72
73 /**
74 * Holds the configured loaders for this MillScript configuration.
75 */
76 protected final LoaderBuilder loaderBuilder = new LoaderBuilder();
77
78 /**
79 * Holds the logger for this MillScript configuration
80 */
81 protected Logger logger = null;
82
83 /**
84 * The current output character set.
85 */
86 protected Charset outputCharset;
87
88 /**
89 * Holds the basic properties defined in the configuration files.
90 */
91 protected final EMap< String, Object > properties = new EHashMap< String, Object >();
92
93 /**
94 * Holds the XML character entities configuration.
95 */
96 protected final CharacterEntity xmlCharacterEntities = new XMLCharacterEntity();
97
98 /**
99 * @see org.millscript.millscript.conf.Configuration#getBooleanProperty(java.lang.String)
100 */
101 public boolean getBooleanProperty( final String key ) {
102 if ( !properties.containsKey( key ) ) {
103 throw(
104 Alerts.fault(
105 "A required configuration property is not defined"
106 ).culprit( "property", key ).mishap()
107 );
108 }
109 return CastLibrary.toBoolean( properties.get( key ) ).booleanValue();
110 }
111
112 /**
113 * @see org.millscript.millscript.conf.Configuration#getCurrentWorkingFolder()
114 */
115 public final VFolder getCurrentWorkingFolder() {
116 return cwd;
117 }
118
119 /**
120 * @see org.millscript.millscript.conf.Configuration#getHTMLCharacterEntity()
121 */
122 public CharacterEntity getHTMLCharacterEntity() {
123 return htmlCharacterEntities;
124 }
125
126 /**
127 * @see org.millscript.millscript.conf.Configuration#getLoaderBuilder()
128 */
129 public LoaderBuilder getLoaderBuilder() {
130 return this.loaderBuilder;
131 }
132
133 /**
134 * @see org.millscript.millscript.conf.Configuration#getLogger()
135 */
136 public Logger getLogger() {
137 return this.logger;
138 }
139
140 /**
141 * @see org.millscript.millscript.conf.Configuration#getOutputCharset()
142 */
143 public Charset getOutputCharset() {
144 return this.outputCharset;
145 }
146
147 /**
148 * @see org.millscript.millscript.conf.Configuration#getPackageConfFile(org.millscript.commons.vfs.VFolder)
149 */
150 public VFile getPackageConfFile( final VFolder packageDir ) {
151 return packageDir.getVFile( PACKAGE_CONF_FILE );
152 }
153
154 /**
155 * @see org.millscript.millscript.conf.Configuration#getProperty(java.lang.String)
156 */
157 public String getProperty( final String key ) {
158 if ( !properties.containsKey( key ) ) {
159 throw(
160 Alerts.fault(
161 "A required configuration property is not defined"
162 ).culprit( "property", key ).mishap()
163 );
164 }
165 return properties.get( key ).toString();
166 }
167
168 /**
169 * @see org.millscript.millscript.conf.Configuration#getStandardEngine()
170 */
171 public Engine getStandardEngine() {
172
173 final StandardEngine engine = new StandardEngine( this );
174
175 engine.setStandardPackage( this.getStandardPackage( engine ) );
176
177
178 engine.addPackage( engine.getStandardPackage() );
179
180 return engine;
181 }
182
183 /**
184 * @see org.millscript.millscript.conf.Configuration#getStandardPackage(org.millscript.millscript.vm.Engine)
185 */
186 public Package getStandardPackage( final Engine engine ) {
187 final Package standardPackage = new Package( engine, "millscript.standard", true );
188
189 standardPackage.bindProtectedConst( "absent", null );
190 standardPackage.bindProtectedConst( "false", Boolean.FALSE );
191 standardPackage.bindProtectedConst( "true", Boolean.TRUE );
192
193 standardPackage.bindProtectedConst(
194 "dateDate",
195 new DateFieldFunction( Calendar.DATE, 0 )
196 );
197 standardPackage.bindProtectedConst(
198 "dateMonth", new DateFieldFunction( Calendar.MONTH, 1 )
199 );
200 standardPackage.bindProtectedConst(
201 "dateYear", new DateFieldFunction( Calendar.YEAR, 0 )
202 );
203
204
205
206 standardPackage.bindProtectedConst(
207 "<",
208 new BinaryFunction() {
209 @Override
210 @SuppressWarnings("unchecked")
211 public Object apply2( final Object x, final Object y ) {
212 return ((Comparable)x).compareTo( y ) < 0 ? Boolean.TRUE : Boolean.FALSE;
213 }
214 }
215 );
216 standardPackage.bindProtectedConst(
217 "<=",
218 new BinaryFunction() {
219 @Override
220 @SuppressWarnings("unchecked")
221 public Object apply2( final Object x, final Object y ) {
222 return ((Comparable)x).compareTo( y ) <= 0 ? Boolean.TRUE : Boolean.FALSE;
223 }
224 }
225 );
226 standardPackage.bindProtectedConst(
227 "=",
228 new BinaryFunction() {
229 @Override
230 public Object apply2( final Object x, final Object y ) {
231 return (
232 x == null ? ( y == null ? Boolean.TRUE : Boolean.FALSE ) :
233 x.equals( y ) ? Boolean.TRUE : Boolean.FALSE
234 );
235 }
236 }
237 );
238 standardPackage.bindProtectedConst(
239 "/=",
240 new BinaryFunction() {
241 @Override
242 public Object apply2( final Object x, final Object y ) {
243 return (
244 x == null ? ( y == null ? Boolean.FALSE : Boolean.TRUE ) :
245 x.equals( y ) ? Boolean.FALSE : Boolean.TRUE
246 );
247 }
248 }
249 );
250 standardPackage.bindProtectedConst(
251 "==",
252 new BinaryFunction() {
253 @Override
254 public Object apply2( final Object x, final Object y ) {
255 return x == y ? Boolean.TRUE : Boolean.FALSE;
256 }
257 }
258 );
259 standardPackage.bindProtectedConst(
260 "/==",
261 new BinaryFunction() {
262 @Override
263 public Object apply2( final Object x, final Object y ) {
264 return x == y ? Boolean.FALSE : Boolean.TRUE;
265 }
266 }
267 );
268 standardPackage.bindProtectedConst(
269 ">=",
270 new BinaryFunction() {
271 @Override
272 @SuppressWarnings("unchecked")
273 public Object apply2( final Object x, final Object y ) {
274 return ((Comparable)x).compareTo( y ) >= 0 ? Boolean.TRUE : Boolean.FALSE;
275 }
276 }
277 );
278 standardPackage.bindProtectedConst(
279 ">",
280 new BinaryFunction() {
281 @Override
282 @SuppressWarnings("unchecked")
283 public Object apply2( final Object x, final Object y ) {
284 return ((Comparable)x).compareTo( y ) > 0 ? Boolean.TRUE : Boolean.FALSE;
285 }
286 }
287 );
288
289 standardPackage.loadConf(
290 new URLSource(
291 Configuration.class.getResource(
292 "/org/millscript/millscript/conf/millscript.conf"
293 )
294 )
295 );
296 standardPackage.loadConf(
297 new URLSource(
298 Configuration.class.getResource(
299 "/org/millscript/millscript/conf/loaders.conf"
300 )
301 )
302 );
303 standardPackage.loadConf(
304 new URLSource(
305 Configuration.class.getResource(
306 "/org/millscript/millscript/conf/entities.conf"
307 )
308 )
309 );
310 standardPackage.loadConf(
311 new URLSource(
312 Configuration.class.getResource(
313 "/org/millscript/millscript/conf/functions.conf"
314 )
315 )
316 );
317
318 try {
319 final Enumeration< URL > plugins = AbstractConfiguration.class.getClassLoader().getResources(
320 "META-INF/millscript/conf/plugin.conf"
321 );
322 while ( plugins.hasMoreElements() ) {
323 standardPackage.loadConf(
324 new URLSource(
325 plugins.nextElement()
326 )
327 );
328 }
329 } catch ( IOException ex ) {
330 throw Alerts.fault(
331 "An unexpected error occurred while trying to load plugins"
332 ).setParentThrowable( ex ).mishap();
333 }
334
335 return standardPackage;
336 }
337
338 /**
339 * @see org.millscript.millscript.conf.Configuration#getVFS()
340 */
341 public VFS getVFS() {
342 return this.vfs;
343 }
344
345 /**
346 * @see org.millscript.millscript.conf.Configuration#getXMLCharacterEntity()
347 */
348 public CharacterEntity getXMLCharacterEntity() {
349 return xmlCharacterEntities;
350 }
351
352 /**
353 * @see org.millscript.millscript.conf.Configuration#reportAlertAsMishap(org.millscript.commons.alert.Alert)
354 */
355 public void reportAlertAsMishap( final Alert alert ) {
356 StandardMishapAlertReporter.MISHAP_REPORTER.report( alert );
357 if ( alert.getParentThrowable() != null ) {
358 this.getLogger().debugLine( "Trying to printStackTrace." );
359 this.getLogger().stackTrace( alert.getParentThrowable() );
360 }
361 }
362
363 /**
364 * @see org.millscript.millscript.conf.Configuration#reportAlertAsWarning(org.millscript.commons.alert.Alert)
365 */
366 public void reportAlertAsWarning( final Alert alert ) {
367 StandardWarningAlertReporter.WARNING_REPORTER.report( alert );
368 }
369
370 /**
371 * @see org.millscript.millscript.conf.Configuration#reportException(java.lang.Exception)
372 */
373 public void reportException( final Exception exception ) {
374
375 if ( exception instanceof EscapeException ) {
376 this.reportAlertAsMishap(
377 ((EscapeException) exception).getAlert()
378 );
379 } else if ( exception instanceof Alert ) {
380 this.reportAlertAsMishap( (Alert) exception );
381 } else {
382 this.getLogger().emerg( "Trapped : " );
383 String cname = exception.getClass().getName();
384 this.getLogger().emergLine( cname );
385 if ( exception.getMessage() != null ) {
386 this.getLogger().emerg( "Message : " );
387 this.getLogger().emergLine( exception.getMessage() );
388 }
389 this.getLogger().debugLine( "Trying to printStackTrace." );
390 this.getLogger().stackTrace( exception );
391 }
392 }
393
394 /**
395 * @see org.millscript.millscript.conf.Configuration#setLogger(org.millscript.millscript.conf.logging.Logger)
396 */
397 public void setLogger( final Logger l ) {
398 this.logger = l;
399 }
400
401 /**
402 * @see org.millscript.millscript.conf.Configuration#setOutputCharset(java.nio.charset.Charset)
403 */
404 public void setOutputCharset( final Charset cs ) {
405 this.outputCharset = cs;
406 }
407
408 /**
409 * @see org.millscript.millscript.conf.Configuration#setProperty(java.lang.String, java.lang.Object)
410 */
411 public void setProperty( final String key, final Object value ) {
412 this.properties.insert( key, value );
413 }
414
415 }