001 /**
002 * <copyright>
003 * </copyright>
004 *
005 * $Id$
006 */
007 package com.hammurapi.config.impl;
008
009 import java.io.File;
010 import java.lang.reflect.InvocationTargetException;
011 import java.net.URL;
012 import java.net.URLClassLoader;
013 import java.util.ArrayList;
014 import java.util.Collection;
015 import java.util.Iterator;
016 import java.util.List;
017 import java.util.logging.Logger;
018
019 import org.codehaus.janino.ScriptEvaluator;
020 import org.eclipse.emf.common.notify.Notification;
021 import org.eclipse.emf.common.notify.NotificationChain;
022 import org.eclipse.emf.common.util.EList;
023 import org.eclipse.emf.ecore.EClass;
024 import org.eclipse.emf.ecore.InternalEObject;
025 import org.eclipse.emf.ecore.impl.ENotificationImpl;
026 import org.eclipse.emf.ecore.impl.EObjectImpl;
027 import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
028 import org.eclipse.emf.ecore.util.EObjectContainmentEList;
029 import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
030 import org.eclipse.emf.ecore.util.InternalEList;
031
032 import com.hammurapi.config.ConfigPackage;
033 import com.hammurapi.config.Constructor;
034 import com.hammurapi.config.Factory;
035 import com.hammurapi.config.Named;
036 import com.hammurapi.config.ObjectDefinition;
037 import com.hammurapi.config.Path;
038 import com.hammurapi.config.Profile;
039 import com.hammurapi.config.PropertySource;
040 import com.hammurapi.config.Source;
041 import com.hammurapi.config.bootstrap.ConfigurationException;
042 import com.hammurapi.config.bootstrap.Destroyable;
043 import com.hammurapi.config.bootstrap.FactoryClosure;
044 import com.hammurapi.config.bootstrap.TokenExpander;
045 import com.hammurapi.config.bootstrap.TokenExpander.TokenSource;
046 import com.hammurapi.config.runtime.Component;
047 import com.hammurapi.config.runtime.ConfigurationContext;
048 import com.hammurapi.config.runtime.DestroyableSink;
049 import com.hammurapi.config.runtime.FactoryConfig;
050 import com.hammurapi.party.PartyPackage;
051 import com.hammurapi.party.Role;
052 import com.hammurapi.config.runtime.FactoryClosureBase;
053 import com.hammurapi.config.runtime.InjectionConfig;
054 import com.hammurapi.convert.ConvertingService;
055 import com.hammurapi.convert.DuckConverterFactory;
056 import com.hammurapi.util.Context;
057 import com.hammurapi.util.MutableContext;
058
059 /**
060 * <!-- begin-user-doc -->
061 * An implementation of the model object '<em><b>Object Definition</b></em>'.
062 * <!-- end-user-doc -->
063 * <p>
064 * The following features are implemented:
065 * <ul>
066 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getRoles <em>Roles</em>}</li>
067 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getDescription <em>Description</em>}</li>
068 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getConfigScript <em>Config Script</em>}</li>
069 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getId <em>Id</em>}</li>
070 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getSource <em>Source</em>}</li>
071 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#isEnabled <em>Enabled</em>}</li>
072 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getService <em>Service</em>}</li>
073 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getSupportedExecutionEnvironments <em>Supported Execution Environments</em>}</li>
074 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getHomePage <em>Home Page</em>}</li>
075 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getProperty <em>Property</em>}</li>
076 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getProfile <em>Profile</em>}</li>
077 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getClassPath <em>Class Path</em>}</li>
078 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getConstructor <em>Constructor</em>}</li>
079 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getValue <em>Value</em>}</li>
080 * <li>{@link com.hammurapi.config.impl.ObjectDefinitionImpl#getType <em>Type</em>}</li>
081 * </ul>
082 * </p>
083 *
084 * @generated
085 */
086 public class ObjectDefinitionImpl extends EObjectImpl implements ObjectDefinition {
087 /**
088 * The cached value of the '{@link #getRoles() <em>Roles</em>}' containment reference list.
089 * <!-- begin-user-doc -->
090 * <!-- end-user-doc -->
091 * @see #getRoles()
092 * @generated
093 * @ordered
094 */
095 protected EList<Role> roles;
096 private static final Logger logger = Logger.getLogger(ObjectDefinitionImpl.class.getName());
097 /**
098 * The default value of the '{@link #getDescription() <em>Description</em>}' attribute.
099 * <!-- begin-user-doc -->
100 * <!-- end-user-doc -->
101 * @see #getDescription()
102 * @generated
103 * @ordered
104 */
105 protected static final String DESCRIPTION_EDEFAULT = null;
106
107 /**
108 * The cached value of the '{@link #getDescription() <em>Description</em>}' attribute.
109 * <!-- begin-user-doc -->
110 * <!-- end-user-doc -->
111 * @see #getDescription()
112 * @generated
113 * @ordered
114 */
115 protected String description = DESCRIPTION_EDEFAULT;
116
117 /**
118 * The default value of the '{@link #getConfigScript() <em>Config Script</em>}' attribute.
119 * <!-- begin-user-doc -->
120 * <!-- end-user-doc -->
121 * @see #getConfigScript()
122 * @generated
123 * @ordered
124 */
125 protected static final String CONFIG_SCRIPT_EDEFAULT = null;
126
127 /**
128 * The cached value of the '{@link #getConfigScript() <em>Config Script</em>}' attribute.
129 * <!-- begin-user-doc -->
130 * <!-- end-user-doc -->
131 * @see #getConfigScript()
132 * @generated
133 * @ordered
134 */
135 protected String configScript = CONFIG_SCRIPT_EDEFAULT;
136
137 /**
138 * The default value of the '{@link #getId() <em>Id</em>}' attribute.
139 * <!-- begin-user-doc -->
140 * <!-- end-user-doc -->
141 * @see #getId()
142 * @generated
143 * @ordered
144 */
145 protected static final String ID_EDEFAULT = null;
146
147 /**
148 * The cached value of the '{@link #getId() <em>Id</em>}' attribute.
149 * <!-- begin-user-doc -->
150 * <!-- end-user-doc -->
151 * @see #getId()
152 * @generated
153 * @ordered
154 */
155 protected String id = ID_EDEFAULT;
156
157 /**
158 * The cached value of the '{@link #getSource() <em>Source</em>}' containment reference list.
159 * <!-- begin-user-doc -->
160 * <!-- end-user-doc -->
161 * @see #getSource()
162 * @generated
163 * @ordered
164 */
165 protected EList<Source> source;
166
167 /**
168 * The default value of the '{@link #isEnabled() <em>Enabled</em>}' attribute.
169 * <!-- begin-user-doc -->
170 * <!-- end-user-doc -->
171 * @see #isEnabled()
172 * @generated
173 * @ordered
174 */
175 protected static final boolean ENABLED_EDEFAULT = true;
176
177 /**
178 * The cached value of the '{@link #isEnabled() <em>Enabled</em>}' attribute.
179 * <!-- begin-user-doc -->
180 * <!-- end-user-doc -->
181 * @see #isEnabled()
182 * @generated
183 * @ordered
184 */
185 protected boolean enabled = ENABLED_EDEFAULT;
186
187 /**
188 * The cached value of the '{@link #getService() <em>Service</em>}' attribute list.
189 * <!-- begin-user-doc -->
190 * <!-- end-user-doc -->
191 * @see #getService()
192 * @generated
193 * @ordered
194 */
195 protected EList<String> service;
196
197 /**
198 * The cached value of the '{@link #getSupportedExecutionEnvironments() <em>Supported Execution Environments</em>}' attribute list.
199 * <!-- begin-user-doc -->
200 * <!-- end-user-doc -->
201 * @see #getSupportedExecutionEnvironments()
202 * @generated
203 * @ordered
204 */
205 protected EList<String> supportedExecutionEnvironments;
206 /**
207 * The default value of the '{@link #getHomePage() <em>Home Page</em>}' attribute.
208 * <!-- begin-user-doc -->
209 * <!-- end-user-doc -->
210 * @see #getHomePage()
211 * @generated
212 * @ordered
213 */
214 protected static final String HOME_PAGE_EDEFAULT = null;
215 /**
216 * The cached value of the '{@link #getHomePage() <em>Home Page</em>}' attribute.
217 * <!-- begin-user-doc -->
218 * <!-- end-user-doc -->
219 * @see #getHomePage()
220 * @generated
221 * @ordered
222 */
223 protected String homePage = HOME_PAGE_EDEFAULT;
224 /**
225 * The cached value of the '{@link #getProperty() <em>Property</em>}' containment reference list.
226 * <!-- begin-user-doc -->
227 * <!-- end-user-doc -->
228 * @see #getProperty()
229 * @generated
230 * @ordered
231 */
232 protected EList<Named> property;
233
234 /**
235 * The cached value of the '{@link #getProfile() <em>Profile</em>}' containment reference list.
236 * <!-- begin-user-doc -->
237 * <!-- end-user-doc -->
238 * @see #getProfile()
239 * @generated
240 * @ordered
241 */
242 protected EList<Profile> profile;
243
244 /**
245 * The cached value of the '{@link #getClassPath() <em>Class Path</em>}' containment reference list.
246 * <!-- begin-user-doc -->
247 * <!-- end-user-doc -->
248 * @see #getClassPath()
249 * @generated
250 * @ordered
251 */
252 protected EList<Path> classPath;
253
254 /**
255 * The cached value of the '{@link #getConstructor() <em>Constructor</em>}' containment reference.
256 * <!-- begin-user-doc -->
257 * <!-- end-user-doc -->
258 * @see #getConstructor()
259 * @generated
260 * @ordered
261 */
262 protected Constructor constructor;
263
264 /**
265 * The default value of the '{@link #getValue() <em>Value</em>}' attribute.
266 * <!-- begin-user-doc -->
267 * <!-- end-user-doc -->
268 * @see #getValue()
269 * @generated
270 * @ordered
271 */
272 protected static final String VALUE_EDEFAULT = null;
273
274 /**
275 * The cached value of the '{@link #getValue() <em>Value</em>}' attribute.
276 * <!-- begin-user-doc -->
277 * <!-- end-user-doc -->
278 * @see #getValue()
279 * @generated
280 * @ordered
281 */
282 protected String value = VALUE_EDEFAULT;
283
284 /**
285 * The default value of the '{@link #getType() <em>Type</em>}' attribute.
286 * <!-- begin-user-doc -->
287 * <!-- end-user-doc -->
288 * @see #getType()
289 * @generated
290 * @ordered
291 */
292 protected static final String TYPE_EDEFAULT = null;
293
294 /**
295 * The cached value of the '{@link #getType() <em>Type</em>}' attribute.
296 * <!-- begin-user-doc -->
297 * <!-- end-user-doc -->
298 * @see #getType()
299 * @generated
300 * @ordered
301 */
302 protected String type = TYPE_EDEFAULT;
303
304 /**
305 * <!-- begin-user-doc -->
306 * <!-- end-user-doc -->
307 * @generated
308 */
309 protected ObjectDefinitionImpl() {
310 super();
311 }
312
313 /**
314 * <!-- begin-user-doc -->
315 * <!-- end-user-doc -->
316 * @generated
317 */
318 @Override
319 protected EClass eStaticClass() {
320 return ConfigPackage.Literals.OBJECT_DEFINITION;
321 }
322
323 /**
324 * <!-- begin-user-doc -->
325 * <!-- end-user-doc -->
326 * @generated
327 */
328 public EList<Role> getRoles() {
329 if (roles == null) {
330 roles = new EObjectContainmentWithInverseEList<Role>(Role.class, this, ConfigPackage.OBJECT_DEFINITION__ROLES, PartyPackage.ROLE__OWNER);
331 }
332 return roles;
333 }
334
335 /**
336 * <!-- begin-user-doc -->
337 * <!-- end-user-doc -->
338 * @generated
339 */
340 public String getDescription() {
341 return description;
342 }
343
344 /**
345 * <!-- begin-user-doc -->
346 * <!-- end-user-doc -->
347 * @generated
348 */
349 public void setDescription(String newDescription) {
350 String oldDescription = description;
351 description = newDescription;
352 if (eNotificationRequired())
353 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__DESCRIPTION, oldDescription, description));
354 }
355
356 /**
357 * <!-- begin-user-doc -->
358 * <!-- end-user-doc -->
359 * @generated
360 */
361 public String getConfigScript() {
362 return configScript;
363 }
364
365 /**
366 * <!-- begin-user-doc -->
367 * <!-- end-user-doc -->
368 * @generated
369 */
370 public void setConfigScript(String newConfigScript) {
371 String oldConfigScript = configScript;
372 configScript = newConfigScript;
373 if (eNotificationRequired())
374 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__CONFIG_SCRIPT, oldConfigScript, configScript));
375 }
376
377 /**
378 * <!-- begin-user-doc -->
379 * <!-- end-user-doc -->
380 * @generated
381 */
382 public String getId() {
383 return id;
384 }
385
386 /**
387 * <!-- begin-user-doc -->
388 * <!-- end-user-doc -->
389 * @generated
390 */
391 public void setId(String newId) {
392 String oldId = id;
393 id = newId;
394 if (eNotificationRequired())
395 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__ID, oldId, id));
396 }
397
398 /**
399 * <!-- begin-user-doc -->
400 * <!-- end-user-doc -->
401 * @generated
402 */
403 public EList<Source> getSource() {
404 if (source == null) {
405 source = new EObjectContainmentEList<Source>(Source.class, this, ConfigPackage.OBJECT_DEFINITION__SOURCE);
406 }
407 return source;
408 }
409
410 /**
411 * <!-- begin-user-doc -->
412 * <!-- end-user-doc -->
413 * @generated
414 */
415 public boolean isEnabled() {
416 return enabled;
417 }
418
419 /**
420 * <!-- begin-user-doc -->
421 * <!-- end-user-doc -->
422 * @generated
423 */
424 public void setEnabled(boolean newEnabled) {
425 boolean oldEnabled = enabled;
426 enabled = newEnabled;
427 if (eNotificationRequired())
428 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__ENABLED, oldEnabled, enabled));
429 }
430
431 /**
432 * <!-- begin-user-doc -->
433 * <!-- end-user-doc -->
434 * @generated
435 */
436 public EList<String> getService() {
437 if (service == null) {
438 service = new EDataTypeUniqueEList<String>(String.class, this, ConfigPackage.OBJECT_DEFINITION__SERVICE);
439 }
440 return service;
441 }
442
443 /**
444 * <!-- begin-user-doc -->
445 * <!-- end-user-doc -->
446 * @generated
447 */
448 public EList<String> getSupportedExecutionEnvironments() {
449 if (supportedExecutionEnvironments == null) {
450 supportedExecutionEnvironments = new EDataTypeUniqueEList<String>(String.class, this, ConfigPackage.OBJECT_DEFINITION__SUPPORTED_EXECUTION_ENVIRONMENTS);
451 }
452 return supportedExecutionEnvironments;
453 }
454
455 /**
456 * <!-- begin-user-doc -->
457 * <!-- end-user-doc -->
458 * @generated
459 */
460 public String getHomePage() {
461 return homePage;
462 }
463
464 /**
465 * <!-- begin-user-doc -->
466 * <!-- end-user-doc -->
467 * @generated
468 */
469 public void setHomePage(String newHomePage) {
470 String oldHomePage = homePage;
471 homePage = newHomePage;
472 if (eNotificationRequired())
473 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__HOME_PAGE, oldHomePage, homePage));
474 }
475
476 /**
477 * <!-- begin-user-doc -->
478 * <!-- end-user-doc -->
479 * @generated
480 */
481 public EList<Named> getProperty() {
482 if (property == null) {
483 property = new EObjectContainmentEList<Named>(Named.class, this, ConfigPackage.OBJECT_DEFINITION__PROPERTY);
484 }
485 return property;
486 }
487
488 /**
489 * <!-- begin-user-doc -->
490 * <!-- end-user-doc -->
491 * @generated
492 */
493 public EList<Profile> getProfile() {
494 if (profile == null) {
495 profile = new EObjectContainmentWithInverseEList<Profile>(Profile.class, this, ConfigPackage.OBJECT_DEFINITION__PROFILE, ConfigPackage.PROFILE__OWNER);
496 }
497 return profile;
498 }
499
500 /**
501 * <!-- begin-user-doc -->
502 * <!-- end-user-doc -->
503 * @generated
504 */
505 public EList<Path> getClassPath() {
506 if (classPath == null) {
507 classPath = new EObjectContainmentEList<Path>(Path.class, this, ConfigPackage.OBJECT_DEFINITION__CLASS_PATH);
508 }
509 return classPath;
510 }
511
512 /**
513 * <!-- begin-user-doc -->
514 * <!-- end-user-doc -->
515 * @generated
516 */
517 public Constructor getConstructor() {
518 return constructor;
519 }
520
521 /**
522 * <!-- begin-user-doc -->
523 * <!-- end-user-doc -->
524 * @generated
525 */
526 public NotificationChain basicSetConstructor(Constructor newConstructor, NotificationChain msgs) {
527 Constructor oldConstructor = constructor;
528 constructor = newConstructor;
529 if (eNotificationRequired()) {
530 ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR, oldConstructor, newConstructor);
531 if (msgs == null) msgs = notification; else msgs.add(notification);
532 }
533 return msgs;
534 }
535
536 /**
537 * <!-- begin-user-doc -->
538 * <!-- end-user-doc -->
539 * @generated
540 */
541 public void setConstructor(Constructor newConstructor) {
542 if (newConstructor != constructor) {
543 NotificationChain msgs = null;
544 if (constructor != null)
545 msgs = ((InternalEObject)constructor).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR, null, msgs);
546 if (newConstructor != null)
547 msgs = ((InternalEObject)newConstructor).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR, null, msgs);
548 msgs = basicSetConstructor(newConstructor, msgs);
549 if (msgs != null) msgs.dispatch();
550 }
551 else if (eNotificationRequired())
552 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR, newConstructor, newConstructor));
553 }
554
555 /**
556 * <!-- begin-user-doc -->
557 * <!-- end-user-doc -->
558 * @generated
559 */
560 public String getValue() {
561 return value;
562 }
563
564 /**
565 * <!-- begin-user-doc -->
566 * <!-- end-user-doc -->
567 * @generated
568 */
569 public void setValue(String newValue) {
570 String oldValue = value;
571 value = newValue;
572 if (eNotificationRequired())
573 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__VALUE, oldValue, value));
574 }
575
576 /**
577 * <!-- begin-user-doc -->
578 * <!-- end-user-doc -->
579 * @generated
580 */
581 public String getType() {
582 return type;
583 }
584
585 /**
586 * <!-- begin-user-doc -->
587 * <!-- end-user-doc -->
588 * @generated
589 */
590 public void setType(String newType) {
591 String oldType = type;
592 type = newType;
593 if (eNotificationRequired())
594 eNotify(new ENotificationImpl(this, Notification.SET, ConfigPackage.OBJECT_DEFINITION__TYPE, oldType, type));
595 }
596
597 /**
598 * <!-- begin-user-doc -->
599 * <!-- end-user-doc -->
600 * @generated NOT
601 */
602 public FactoryClosure<Object> create(final FactoryConfig factoryConfig) throws ConfigurationException {
603
604 return new FactoryClosureBase<Object>() {
605
606 @SuppressWarnings("unchecked")
607 public Object create(Object... cArgs) throws ConfigurationException {
608
609 ClassLoader classLoader = propertySourceClassLoader(ObjectDefinitionImpl.this, factoryConfig);
610
611 // Find constructor, instantiate
612 String className = getType();
613
614
615 TokenExpander tokenExpander = factoryConfig.getTokenSource()==null ? null : new TokenExpander(factoryConfig.getTokenSource());
616
617 String theValue = getValue();
618 if (tokenExpander!=null && theValue!=null && theValue.trim().length()>0) {
619 theValue = tokenExpander.expand(theValue);
620 }
621
622 if (tokenExpander!=null && className!=null) {
623 className = tokenExpander.expand(className);
624 }
625
626 // No class name - String.
627 if (className==null || className.trim().length()==0) {
628 className = String.class.getName();
629 }
630
631 logger.fine("Creating a new object definition of type "+className);
632
633 Class<?> clazz;
634 try {
635 clazz = classLoader.loadClass(className);
636 } catch (ClassNotFoundException e) {
637 throw new ConfigurationException(e);
638 }
639
640 Object instance=null;
641
642 java.lang.reflect.Constructor<?>[] constructors = clazz.getDeclaredConstructors();
643 if (getConstructor()==null) {
644 if (theValue!=null && theValue.trim().length()>0) {
645 if (cArgs.length>0) {
646 throw new ConfigurationException("create() with arguments is not compatible with value attribute");
647 }
648 // Single argument constructor.
649 if (tokenExpander!=null) {
650 theValue = tokenExpander.expand(theValue);
651 }
652 instance = construct(theValue, constructors, className, factoryConfig.getContextUrl());
653 if (instance==null) { // No constructor, try conversion.
654 instance = ConvertingService.convert(theValue, clazz, factoryConfig.getClassLoader());
655 if (instance==null) {
656 throw new ConfigurationException("Cannot create instance of "+clazz.getName()+" from '"+theValue+"'");
657 }
658 }
659 } else {
660 if (String.class.equals(clazz) && cArgs.length==0) {
661 instance="";
662 } else {
663 // Construct
664 try {
665 instance = construct(clazz, cArgs);
666 } catch (InstantiationException e) {
667 throw new ConfigurationException(e);
668 } catch (IllegalAccessException e) {
669 throw new ConfigurationException(e);
670 }
671 }
672 }
673 } else {
674 if (theValue!=null && theValue.trim().length()>0) {
675 throw new ConfigurationException("value and constructor are mutually exclusive");
676 }
677 if (cArgs.length>0) {
678 throw new ConfigurationException("create() with arguments and constructor definition are incompatible");
679 }
680 Object[] args = new Object[getConstructor().getArgument().size()];
681 Iterator<Factory> ait = getConstructor().getArgument().iterator();
682 FactoryConfig argConfig;
683 try {
684 argConfig = (FactoryConfig) factoryConfig.clone();
685 } catch (CloneNotSupportedException ex) {
686 throw new ConfigurationException(ex);
687 }
688 argConfig.setClassLoader(classLoader);
689 for (int i=0; ait.hasNext(); ++i) {
690 FactoryClosure<Object> afr = ait.next().create(argConfig);
691 try {
692 args[i] = afr.create();
693 } catch (Exception e) {
694 throw new ConfigurationException(e);
695 }
696 destroyableSink.addDestroyable(afr.getDestroyable());
697 }
698 instance = construct(args, constructors, className);
699 }
700
701 if (instance==null) {
702 throw new ConfigurationException("Could not instantiate object"); // Should never come here.
703 }
704
705 // Properties from profile/root.
706 InjectionConfig injectionConfig = new InjectionConfig(factoryConfig, destroyableSink);
707 injectionConfig.setClassLoader(classLoader);
708 injectionConfig.setObjectPath(new Object[] {instance});
709 injectionConfig.setTarget(instance);
710
711 matchProfile(ObjectDefinitionImpl.this, injectionConfig.getProfilePath(), 0).injectProperties(injectionConfig);
712
713 ObjectDefinition def = ObjectDefinitionImpl.this;
714 // Init.
715 if (instance instanceof Component) {
716 Component<ObjectDefinition> comp = (Component<ObjectDefinition>) instance;
717 ConfigurationContext<ObjectDefinition> context = (ConfigurationContext<ObjectDefinition>) factoryConfig.getContextFactory().createContext(def, comp, factoryConfig, destroyableSink);
718 comp.init(context);
719 }
720
721 // Execute script once everything is initialized.
722 if (getConfigScript()!=null && getConfigScript().trim().length()>0) {
723 ScriptEvaluator se = new ScriptEvaluator();
724 se.setParameters(new String[] {"instance", "definition", "config"}, new Class[] {instance.getClass(), def.getClass(), factoryConfig.getClass()});
725 se.setParentClassLoader(classLoader);
726 se.setThrownExceptions(new Class[] {ConfigurationException.class});
727 try {
728 se.cook(getConfigScript());
729 se.evaluate(new Object[] {instance, def, factoryConfig});
730 } catch (Exception e) {
731 throw new ConfigurationException(e);
732 }
733 }
734
735 expose(ObjectDefinitionImpl.this, instance, factoryConfig.getContext(), classLoader, destroyableSink);
736 toDestroy(instance);
737 return instance;
738 }
739
740 };
741 }
742
743 public static ClassLoader propertySourceClassLoader(PropertySource propertySource, FactoryConfig factoryConfig) throws ConfigurationException {
744
745 // Match profile
746 PropertySource profile = matchProfile(propertySource, factoryConfig.getProfilePath(), 0);
747 // Classpath
748 List<URL> pathElements = new ArrayList<URL>();
749 for (PropertySource ps = profile; ps!=null; ps = (ps instanceof Profile) ? ((Profile) ps).getOwner() : null) {
750 for (Path path: ps.getClassPath()) {
751 pathElements.addAll(path.getUrls(factoryConfig.getContextUrl(), factoryConfig.getTokenSource()));
752 }
753 }
754
755 ClassLoader classLoader = factoryConfig.getClassLoader();
756 if (classLoader==null) {
757 classLoader = propertySource.getClass().getClassLoader();
758 }
759
760 if (pathElements.isEmpty()) {
761 logger.fine("No path elements, returning parent classloader");
762 return classLoader;
763 }
764
765 logger.fine("Constructing URL classloader from "+pathElements);
766 return new URLClassLoader(pathElements.toArray(new URL[pathElements.size()]), classLoader);
767 }
768
769 /**
770 * <!-- begin-user-doc -->
771 * <!-- end-user-doc -->
772 * @generated
773 */
774 public void compile(EList<String> profilePath, TokenSource tokens, ClassLoader classLoader, File dir, String targetPackage, String targetClass) throws ConfigurationException {
775 // TODO: implement this method
776 // Ensure that you remove @generated or mark it @generated NOT
777 throw new UnsupportedOperationException();
778 }
779
780 /**
781 * <!-- begin-user-doc -->
782 * <!-- end-user-doc -->
783 * @generated
784 */
785 @SuppressWarnings("unchecked")
786 @Override
787 public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
788 switch (featureID) {
789 case ConfigPackage.OBJECT_DEFINITION__ROLES:
790 return ((InternalEList<InternalEObject>)(InternalEList<?>)getRoles()).basicAdd(otherEnd, msgs);
791 case ConfigPackage.OBJECT_DEFINITION__PROFILE:
792 return ((InternalEList<InternalEObject>)(InternalEList<?>)getProfile()).basicAdd(otherEnd, msgs);
793 }
794 return super.eInverseAdd(otherEnd, featureID, msgs);
795 }
796
797 /**
798 * <!-- begin-user-doc -->
799 * <!-- end-user-doc -->
800 * @generated
801 */
802 @Override
803 public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
804 switch (featureID) {
805 case ConfigPackage.OBJECT_DEFINITION__ROLES:
806 return ((InternalEList<?>)getRoles()).basicRemove(otherEnd, msgs);
807 case ConfigPackage.OBJECT_DEFINITION__SOURCE:
808 return ((InternalEList<?>)getSource()).basicRemove(otherEnd, msgs);
809 case ConfigPackage.OBJECT_DEFINITION__PROPERTY:
810 return ((InternalEList<?>)getProperty()).basicRemove(otherEnd, msgs);
811 case ConfigPackage.OBJECT_DEFINITION__PROFILE:
812 return ((InternalEList<?>)getProfile()).basicRemove(otherEnd, msgs);
813 case ConfigPackage.OBJECT_DEFINITION__CLASS_PATH:
814 return ((InternalEList<?>)getClassPath()).basicRemove(otherEnd, msgs);
815 case ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR:
816 return basicSetConstructor(null, msgs);
817 }
818 return super.eInverseRemove(otherEnd, featureID, msgs);
819 }
820
821 /**
822 * <!-- begin-user-doc -->
823 * <!-- end-user-doc -->
824 * @generated
825 */
826 @Override
827 public Object eGet(int featureID, boolean resolve, boolean coreType) {
828 switch (featureID) {
829 case ConfigPackage.OBJECT_DEFINITION__ROLES:
830 return getRoles();
831 case ConfigPackage.OBJECT_DEFINITION__DESCRIPTION:
832 return getDescription();
833 case ConfigPackage.OBJECT_DEFINITION__CONFIG_SCRIPT:
834 return getConfigScript();
835 case ConfigPackage.OBJECT_DEFINITION__ID:
836 return getId();
837 case ConfigPackage.OBJECT_DEFINITION__SOURCE:
838 return getSource();
839 case ConfigPackage.OBJECT_DEFINITION__ENABLED:
840 return isEnabled();
841 case ConfigPackage.OBJECT_DEFINITION__SERVICE:
842 return getService();
843 case ConfigPackage.OBJECT_DEFINITION__SUPPORTED_EXECUTION_ENVIRONMENTS:
844 return getSupportedExecutionEnvironments();
845 case ConfigPackage.OBJECT_DEFINITION__HOME_PAGE:
846 return getHomePage();
847 case ConfigPackage.OBJECT_DEFINITION__PROPERTY:
848 return getProperty();
849 case ConfigPackage.OBJECT_DEFINITION__PROFILE:
850 return getProfile();
851 case ConfigPackage.OBJECT_DEFINITION__CLASS_PATH:
852 return getClassPath();
853 case ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR:
854 return getConstructor();
855 case ConfigPackage.OBJECT_DEFINITION__VALUE:
856 return getValue();
857 case ConfigPackage.OBJECT_DEFINITION__TYPE:
858 return getType();
859 }
860 return super.eGet(featureID, resolve, coreType);
861 }
862
863 /**
864 * <!-- begin-user-doc -->
865 * <!-- end-user-doc -->
866 * @generated
867 */
868 @SuppressWarnings("unchecked")
869 @Override
870 public void eSet(int featureID, Object newValue) {
871 switch (featureID) {
872 case ConfigPackage.OBJECT_DEFINITION__ROLES:
873 getRoles().clear();
874 getRoles().addAll((Collection<? extends Role>)newValue);
875 return;
876 case ConfigPackage.OBJECT_DEFINITION__DESCRIPTION:
877 setDescription((String)newValue);
878 return;
879 case ConfigPackage.OBJECT_DEFINITION__CONFIG_SCRIPT:
880 setConfigScript((String)newValue);
881 return;
882 case ConfigPackage.OBJECT_DEFINITION__ID:
883 setId((String)newValue);
884 return;
885 case ConfigPackage.OBJECT_DEFINITION__SOURCE:
886 getSource().clear();
887 getSource().addAll((Collection<? extends Source>)newValue);
888 return;
889 case ConfigPackage.OBJECT_DEFINITION__ENABLED:
890 setEnabled((Boolean)newValue);
891 return;
892 case ConfigPackage.OBJECT_DEFINITION__SERVICE:
893 getService().clear();
894 getService().addAll((Collection<? extends String>)newValue);
895 return;
896 case ConfigPackage.OBJECT_DEFINITION__SUPPORTED_EXECUTION_ENVIRONMENTS:
897 getSupportedExecutionEnvironments().clear();
898 getSupportedExecutionEnvironments().addAll((Collection<? extends String>)newValue);
899 return;
900 case ConfigPackage.OBJECT_DEFINITION__HOME_PAGE:
901 setHomePage((String)newValue);
902 return;
903 case ConfigPackage.OBJECT_DEFINITION__PROPERTY:
904 getProperty().clear();
905 getProperty().addAll((Collection<? extends Named>)newValue);
906 return;
907 case ConfigPackage.OBJECT_DEFINITION__PROFILE:
908 getProfile().clear();
909 getProfile().addAll((Collection<? extends Profile>)newValue);
910 return;
911 case ConfigPackage.OBJECT_DEFINITION__CLASS_PATH:
912 getClassPath().clear();
913 getClassPath().addAll((Collection<? extends Path>)newValue);
914 return;
915 case ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR:
916 setConstructor((Constructor)newValue);
917 return;
918 case ConfigPackage.OBJECT_DEFINITION__VALUE:
919 setValue((String)newValue);
920 return;
921 case ConfigPackage.OBJECT_DEFINITION__TYPE:
922 setType((String)newValue);
923 return;
924 }
925 super.eSet(featureID, newValue);
926 }
927
928 /**
929 * <!-- begin-user-doc -->
930 * <!-- end-user-doc -->
931 * @generated
932 */
933 @Override
934 public void eUnset(int featureID) {
935 switch (featureID) {
936 case ConfigPackage.OBJECT_DEFINITION__ROLES:
937 getRoles().clear();
938 return;
939 case ConfigPackage.OBJECT_DEFINITION__DESCRIPTION:
940 setDescription(DESCRIPTION_EDEFAULT);
941 return;
942 case ConfigPackage.OBJECT_DEFINITION__CONFIG_SCRIPT:
943 setConfigScript(CONFIG_SCRIPT_EDEFAULT);
944 return;
945 case ConfigPackage.OBJECT_DEFINITION__ID:
946 setId(ID_EDEFAULT);
947 return;
948 case ConfigPackage.OBJECT_DEFINITION__SOURCE:
949 getSource().clear();
950 return;
951 case ConfigPackage.OBJECT_DEFINITION__ENABLED:
952 setEnabled(ENABLED_EDEFAULT);
953 return;
954 case ConfigPackage.OBJECT_DEFINITION__SERVICE:
955 getService().clear();
956 return;
957 case ConfigPackage.OBJECT_DEFINITION__SUPPORTED_EXECUTION_ENVIRONMENTS:
958 getSupportedExecutionEnvironments().clear();
959 return;
960 case ConfigPackage.OBJECT_DEFINITION__HOME_PAGE:
961 setHomePage(HOME_PAGE_EDEFAULT);
962 return;
963 case ConfigPackage.OBJECT_DEFINITION__PROPERTY:
964 getProperty().clear();
965 return;
966 case ConfigPackage.OBJECT_DEFINITION__PROFILE:
967 getProfile().clear();
968 return;
969 case ConfigPackage.OBJECT_DEFINITION__CLASS_PATH:
970 getClassPath().clear();
971 return;
972 case ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR:
973 setConstructor((Constructor)null);
974 return;
975 case ConfigPackage.OBJECT_DEFINITION__VALUE:
976 setValue(VALUE_EDEFAULT);
977 return;
978 case ConfigPackage.OBJECT_DEFINITION__TYPE:
979 setType(TYPE_EDEFAULT);
980 return;
981 }
982 super.eUnset(featureID);
983 }
984
985 /**
986 * <!-- begin-user-doc -->
987 * <!-- end-user-doc -->
988 * @generated
989 */
990 @Override
991 public boolean eIsSet(int featureID) {
992 switch (featureID) {
993 case ConfigPackage.OBJECT_DEFINITION__ROLES:
994 return roles != null && !roles.isEmpty();
995 case ConfigPackage.OBJECT_DEFINITION__DESCRIPTION:
996 return DESCRIPTION_EDEFAULT == null ? description != null : !DESCRIPTION_EDEFAULT.equals(description);
997 case ConfigPackage.OBJECT_DEFINITION__CONFIG_SCRIPT:
998 return CONFIG_SCRIPT_EDEFAULT == null ? configScript != null : !CONFIG_SCRIPT_EDEFAULT.equals(configScript);
999 case ConfigPackage.OBJECT_DEFINITION__ID:
1000 return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
1001 case ConfigPackage.OBJECT_DEFINITION__SOURCE:
1002 return source != null && !source.isEmpty();
1003 case ConfigPackage.OBJECT_DEFINITION__ENABLED:
1004 return enabled != ENABLED_EDEFAULT;
1005 case ConfigPackage.OBJECT_DEFINITION__SERVICE:
1006 return service != null && !service.isEmpty();
1007 case ConfigPackage.OBJECT_DEFINITION__SUPPORTED_EXECUTION_ENVIRONMENTS:
1008 return supportedExecutionEnvironments != null && !supportedExecutionEnvironments.isEmpty();
1009 case ConfigPackage.OBJECT_DEFINITION__HOME_PAGE:
1010 return HOME_PAGE_EDEFAULT == null ? homePage != null : !HOME_PAGE_EDEFAULT.equals(homePage);
1011 case ConfigPackage.OBJECT_DEFINITION__PROPERTY:
1012 return property != null && !property.isEmpty();
1013 case ConfigPackage.OBJECT_DEFINITION__PROFILE:
1014 return profile != null && !profile.isEmpty();
1015 case ConfigPackage.OBJECT_DEFINITION__CLASS_PATH:
1016 return classPath != null && !classPath.isEmpty();
1017 case ConfigPackage.OBJECT_DEFINITION__CONSTRUCTOR:
1018 return constructor != null;
1019 case ConfigPackage.OBJECT_DEFINITION__VALUE:
1020 return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value);
1021 case ConfigPackage.OBJECT_DEFINITION__TYPE:
1022 return TYPE_EDEFAULT == null ? type != null : !TYPE_EDEFAULT.equals(type);
1023 }
1024 return super.eIsSet(featureID);
1025 }
1026
1027 /**
1028 * <!-- begin-user-doc -->
1029 * <!-- end-user-doc -->
1030 * @generated
1031 */
1032 @Override
1033 public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
1034 if (baseClass == PropertySource.class) {
1035 switch (derivedFeatureID) {
1036 case ConfigPackage.OBJECT_DEFINITION__PROPERTY: return ConfigPackage.PROPERTY_SOURCE__PROPERTY;
1037 case ConfigPackage.OBJECT_DEFINITION__PROFILE: return ConfigPackage.PROPERTY_SOURCE__PROFILE;
1038 case ConfigPackage.OBJECT_DEFINITION__CLASS_PATH: return ConfigPackage.PROPERTY_SOURCE__CLASS_PATH;
1039 default: return -1;
1040 }
1041 }
1042 return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
1043 }
1044
1045 /**
1046 * <!-- begin-user-doc -->
1047 * <!-- end-user-doc -->
1048 * @generated
1049 */
1050 @Override
1051 public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
1052 if (baseClass == PropertySource.class) {
1053 switch (baseFeatureID) {
1054 case ConfigPackage.PROPERTY_SOURCE__PROPERTY: return ConfigPackage.OBJECT_DEFINITION__PROPERTY;
1055 case ConfigPackage.PROPERTY_SOURCE__PROFILE: return ConfigPackage.OBJECT_DEFINITION__PROFILE;
1056 case ConfigPackage.PROPERTY_SOURCE__CLASS_PATH: return ConfigPackage.OBJECT_DEFINITION__CLASS_PATH;
1057 default: return -1;
1058 }
1059 }
1060 return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
1061 }
1062
1063 /**
1064 * <!-- begin-user-doc -->
1065 * <!-- end-user-doc -->
1066 * @generated
1067 */
1068 @Override
1069 public String toString() {
1070 if (eIsProxy()) return super.toString();
1071
1072 StringBuffer result = new StringBuffer(super.toString());
1073 result.append(" (description: ");
1074 result.append(description);
1075 result.append(", configScript: ");
1076 result.append(configScript);
1077 result.append(", id: ");
1078 result.append(id);
1079 result.append(", enabled: ");
1080 result.append(enabled);
1081 result.append(", service: ");
1082 result.append(service);
1083 result.append(", supportedExecutionEnvironments: ");
1084 result.append(supportedExecutionEnvironments);
1085 result.append(", homePage: ");
1086 result.append(homePage);
1087 result.append(", value: ");
1088 result.append(value);
1089 result.append(", type: ");
1090 result.append(type);
1091 result.append(')');
1092 return result.toString();
1093 }
1094
1095 public void injectProperties(final InjectionConfig injectionConfig) throws ConfigurationException {
1096 for (Named property: getProperty()) {
1097 if (property.isRuntime() && property.isEnabled()) {
1098 String propertyName = ProfileImpl.propertyName(property);
1099 if (!injectionConfig.getAlreadyInjected().contains(propertyName)) {
1100 property.inject(injectionConfig);
1101 }
1102 }
1103 }
1104 }
1105
1106 /**
1107 * Matches profile path with defined profiles.
1108 * @param ps Property source.
1109 * @param profilePath Profile path.
1110 * @param idx Current match index.
1111 * @return Longest matched profile.
1112 */
1113 static PropertySource matchProfile(
1114 PropertySource ps,
1115 String[] profilePath,
1116 int idx) {
1117
1118 if (profilePath!=null && profilePath.length>idx) {
1119 for (Profile profile: ps.getProfile()) {
1120 if (profile.getName().equals(profilePath[idx])) {
1121 return matchProfile(profile, profilePath, idx+1);
1122 }
1123 }
1124 }
1125
1126 return ps;
1127 }
1128
1129 /**
1130 * Finds appropriate constructor and instantiates object.
1131 * @param args Arguments.
1132 * @param constructors Constructors.
1133 * @param className Class name.
1134 * @return Instantiated object.
1135 * @throws ConfigurationException
1136 */
1137 static Object construct(Object[] args, java.lang.reflect.Constructor<?>[] constructors, String className) throws ConfigurationException {
1138 logger.fine("Constructing "+className);
1139
1140 // Matching number of arguments, convertable types.
1141 Collection<java.lang.reflect.Constructor<?>> candidates = new ArrayList<java.lang.reflect.Constructor<?>>();
1142 for (java.lang.reflect.Constructor<?> constructor: constructors) {
1143 Class<?>[] parameterTypes = constructor.getParameterTypes();
1144 if (parameterTypes.length==args.length) {
1145 candidates.add(constructor); // Matching number of arguments.
1146 }
1147 }
1148
1149 // No conversion instantiation
1150 java.lang.reflect.Constructor<?> noConversionCandidate = null;
1151 int noConversionAffinitiy = -1;
1152 Y: for (java.lang.reflect.Constructor<?> constructor: candidates) {
1153 Class<?>[] parameterTypes = constructor.getParameterTypes();
1154 int newAffinity = 0;
1155 for (int i=0; i<args.length; ++i) {
1156 if (args[i]!=null && !parameterTypes[i].isInstance(args[i])) {
1157 continue Y; // Incompatible.
1158 }
1159
1160 if (args[i]!=null) {
1161 newAffinity+=DuckConverterFactory.classAffinity(args[i].getClass(), parameterTypes[i]);
1162 }
1163
1164 if (noConversionCandidate==null || noConversionAffinitiy>newAffinity) {
1165 noConversionAffinitiy = newAffinity;
1166 noConversionCandidate = constructor;
1167 }
1168 }
1169 }
1170
1171 if (noConversionCandidate!=null) {
1172 try {
1173 return noConversionCandidate.newInstance(args);
1174 } catch (InstantiationException e) {
1175 throw new ConfigurationException(e);
1176 } catch (IllegalAccessException e) {
1177 throw new ConfigurationException(e);
1178 } catch (InvocationTargetException e) {
1179 throw new ConfigurationException(e);
1180 }
1181 }
1182
1183 // Conversion instantiation
1184 Z: for (java.lang.reflect.Constructor<?> constructor: candidates) {
1185 Class<?>[] parameterTypes = constructor.getParameterTypes();
1186 Object[] convertedArgs = new Object[args.length];
1187 for (int i=0; i<args.length; ++i) {
1188 if (args[i]==null || parameterTypes[i].isInstance(args[i])) {
1189 convertedArgs[i] = args[i];
1190 } else {
1191 Object carg = ConvertingService.convert(args[i], parameterTypes[i]);
1192 if (carg==null) {
1193 continue Z;
1194 }
1195 convertedArgs[i] = carg;
1196 }
1197 }
1198 try {
1199 return constructor.newInstance(convertedArgs);
1200 } catch (InstantiationException e) {
1201 throw new ConfigurationException(e);
1202 } catch (IllegalAccessException e) {
1203 throw new ConfigurationException(e);
1204 } catch (InvocationTargetException e) {
1205 throw new ConfigurationException(e);
1206 }
1207 }
1208
1209
1210 throw new ConfigurationException("Could not find appropriate constructor with "+args.length+" parameters for "+className);
1211 }
1212
1213 /**
1214 * Constructs object from string value.
1215 * @param theValue String value.
1216 * @param constructors Constructors.
1217 * @param className Class name.
1218 * @return Instantiated object.
1219 * @throws ConfigurationException
1220 */
1221 static Object construct(String theValue, java.lang.reflect.Constructor<?>[] constructors, String className, URL context) throws ConfigurationException {
1222 logger.fine("Constructing "+className+" from '"+theValue+"'");
1223
1224 // Special handling of URL
1225 if (context!=null && URL.class.getName().equals(className)) {
1226 for (java.lang.reflect.Constructor<?> constructor: constructors) {
1227 Class<?>[] parameterTypes = constructor.getParameterTypes();
1228 if (parameterTypes.length==2 && URL.class.equals(parameterTypes[0]) && String.class.equals(parameterTypes[1])) {
1229 try {
1230 return constructor.newInstance(context, theValue);
1231 } catch (InstantiationException e) {
1232 throw new ConfigurationException(e);
1233 } catch (IllegalAccessException e) {
1234 throw new ConfigurationException(e);
1235 } catch (InvocationTargetException e) {
1236 throw new ConfigurationException(e);
1237 }
1238 }
1239 }
1240
1241 }
1242
1243 // Looking for a string constructor.
1244 for (java.lang.reflect.Constructor<?> constructor: constructors) {
1245 Class<?>[] parameterTypes = constructor.getParameterTypes();
1246 if (parameterTypes.length==1 && String.class.equals(parameterTypes[0])) {
1247 try {
1248 return constructor.newInstance(theValue);
1249 } catch (InstantiationException e) {
1250 throw new ConfigurationException(e);
1251 } catch (IllegalAccessException e) {
1252 throw new ConfigurationException(e);
1253 } catch (InvocationTargetException e) {
1254 throw new ConfigurationException(e);
1255 }
1256 }
1257 }
1258
1259 // Looking for no-conversion constructor
1260 for (java.lang.reflect.Constructor<?> constructor: constructors) {
1261 Class<?>[] parameterTypes = constructor.getParameterTypes();
1262 if (parameterTypes.length==1 && parameterTypes[0].isAssignableFrom(String.class)) {
1263 try {
1264 return constructor.newInstance(theValue);
1265 } catch (InstantiationException e) {
1266 throw new ConfigurationException(e);
1267 } catch (IllegalAccessException e) {
1268 throw new ConfigurationException(e);
1269 } catch (InvocationTargetException e) {
1270 throw new ConfigurationException(e);
1271 }
1272 }
1273 }
1274
1275 // Looking for conversion constructor
1276 for (java.lang.reflect.Constructor<?> constructor: constructors) {
1277 Class<?>[] parameterTypes = constructor.getParameterTypes();
1278 if (parameterTypes.length==1) {
1279 try {
1280 Object arg = ConvertingService.convert(theValue, parameterTypes[0]);
1281 if (arg!=null) {
1282 return constructor.newInstance(arg);
1283 }
1284 } catch (InstantiationException e) {
1285 throw new ConfigurationException(e);
1286 } catch (IllegalAccessException e) {
1287 throw new ConfigurationException(e);
1288 } catch (InvocationTargetException e) {
1289 throw new ConfigurationException(e);
1290 }
1291 }
1292 }
1293
1294 return null;
1295 }
1296
1297 @SuppressWarnings("unchecked")
1298 static void expose(final Factory factory, Object instance, final Context context, ClassLoader classLoader, DestroyableSink destroyableSink) throws ConfigurationException {
1299 if (factory.getId()!=null && factory.getId().trim().length()>0) {
1300 if (context instanceof MutableContext) {
1301 ((MutableContext) context).bind(factory.getId(), instance);
1302 destroyableSink.addDestroyable(new Destroyable() {
1303
1304 public void destroy() throws ConfigurationException {
1305 ((MutableContext) context).unbind(factory.getId());
1306 }
1307
1308 });
1309 } else {
1310 throw new ConfigurationException("Cannot bind "+factory.getId()+" to immutable context");
1311 }
1312 }
1313
1314 for (String service: factory.getService()) {
1315 if (service!=null && service.trim().length()>0) {
1316 if (context instanceof MutableContext) {
1317 try {
1318 final Class<Object> serviceType = (Class<Object>) classLoader.loadClass(service.trim());
1319 final Object converted = ConvertingService.convert(instance, serviceType);
1320 if (converted==null) {
1321 throw new ConfigurationException("Cannot convert "+instance+" to service type "+serviceType);
1322 }
1323 ((MutableContext) context).register(serviceType, converted);
1324 destroyableSink.addDestroyable(new Destroyable() {
1325
1326 public void destroy() throws ConfigurationException {
1327 ((MutableContext) context).unregister(serviceType, converted);
1328 }
1329
1330 });
1331 } catch (ClassNotFoundException e) {
1332 throw new ConfigurationException("Service class not found: "+service);
1333 }
1334 } else {
1335 throw new ConfigurationException("Cannot register "+service+" to immutable context");
1336 }
1337 }
1338 }
1339 }
1340
1341 static Object construct(Class<?> clazz, Object[] args) throws InstantiationException, IllegalAccessException, SecurityException, ConfigurationException {
1342 if (args.length==0) {
1343 return clazz.newInstance();
1344 }
1345
1346 return construct(args, clazz.getConstructors(), clazz.getName());
1347 }
1348
1349
1350
1351 } //ObjectDefinitionImpl