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