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