summaryrefslogtreecommitdiffstats
path: root/tags/java-M1-final/java/sca/core/src/main/java/org/apache/tuscany/core/system/config/SystemContextFactory.java
blob: 2e4a2916ce68459162854427d320aacf36bb014c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/**
 *
 * Copyright 2005 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.tuscany.core.system.config;

import org.apache.tuscany.common.TuscanyRuntimeException;
import org.apache.tuscany.core.builder.ContextCreationException;
import org.apache.tuscany.core.builder.ContextFactory;
import org.apache.tuscany.core.builder.ContextResolver;
import org.apache.tuscany.core.config.ConfigurationException;
import org.apache.tuscany.core.context.CompositeContext;
import org.apache.tuscany.core.context.Context;
import org.apache.tuscany.core.injection.EventInvoker;
import org.apache.tuscany.core.injection.Injector;
import org.apache.tuscany.core.injection.PojoObjectFactory;
import org.apache.tuscany.core.wire.SourceWireFactory;
import org.apache.tuscany.core.wire.TargetWireFactory;
import org.apache.tuscany.core.system.context.SystemAtomicContext;
import org.apache.tuscany.model.assembly.Module;
import org.apache.tuscany.model.assembly.Scope;

import java.lang.reflect.Constructor;
import java.util.List;
import java.util.Map;

/**
 * A <code>ContextFactory</code> that handles system component implementation types, which may be either simple, leaf
 * types or an composites.
 * <p>
 * For composite types, this factory delegates to an {@link org.apache.tuscany.core.builder.ObjectFactory} to create an
 * instance of the composite implementation and perform injection of configuration and references. Once an composite
 * instance is created, the factory will register the composite's children. This process may be done recursively in a
 * lazy fashion, descending down an composite hierarchy as a child composite is instantiated.
 *
 * @version $Rev$ $Date$
 */
public class SystemContextFactory implements ContextFactory<Context>, ContextResolver {

    // the component name as configured in the hosting module
    private String name;

    // if this factory produces composites, the module will be the logical model associated with its children
    private Module module;

    private CompositeContext parentContext;

    // the implementation type constructor
    private Constructor ctr;

    // injectors for properties, references and other metadata values such as @Context
    private List<Injector> setters;

    // an invoker for a method decorated with @Init
    private EventInvoker init;

    // whether the component should be eagerly initialized when its scope starts
    private boolean eagerInit;

    // an invoker for a method decorated with @Destroy
    private EventInvoker destroy;

    // the scope of the implementation instance
    private Scope scope;

    // if the component implementation scope is stateless
    private boolean stateless;

    // if the component implementation is an composite context
    private boolean isComposite;

    /**
     * Creates the runtime configuration
     * 
     * @param name the SCDL name of the component the context refers to
     * @param ctr the implementation type constructor
     * @param scope the scope of the component implementation type
     */
    public SystemContextFactory(String name, Constructor ctr, Scope scope) {
        this(name, null, ctr, scope);
    }

    /**
     * Creates the runtime configuration
     * 
     * @param name the SCDL name of the component the context refers to
     * @param module if this factory produces aggregagtes, the logical model associated with its children; otherwise
     *        null
     * @param ctr the implementation type constructor
     * @param scope the scope of the component implementation type
     */
    public SystemContextFactory(String name, Module module, Constructor ctr, Scope scope) {
        assert (name != null) : "Name was null";
        assert (ctr != null) : "Constructor was null";
        this.name = name;
        this.module = module;
        this.ctr = ctr;
        this.isComposite = CompositeContext.class.isAssignableFrom(ctr.getDeclaringClass());
        this.scope = scope;
        if (isComposite) {
            scope = Scope.AGGREGATE;
        } else {
            stateless = (scope == Scope.INSTANCE);
        }
    }

    public String getName() {
        return name;
    }

    public void addProperty(String propertyName, Object value) {

    }

    public Scope getScope() {
        return scope;
    }

    public Context createContext() throws ContextCreationException {
        if (isComposite) {
            try {
                // composite context types are themselves an instance context
                PojoObjectFactory<CompositeContext> objectFactory = new PojoObjectFactory<CompositeContext>(ctr, null, setters);
                CompositeContext ctx = objectFactory.getInstance();
                ctx.setName(name);
                // the composite has been created, now register its children
                if (module != null) {
                    try {
                        ctx.registerModelObject(module);
                    } catch (ConfigurationException e) {
                        ContextCreationException cce = new ContextCreationException("Error creating context", e);
                        cce.setIdentifier(getName());
                        throw cce;
                    }

                }
                return ctx;
            } catch (TuscanyRuntimeException e) {
                e.addContextName(name);
                throw e;
            }
        } else {
            PojoObjectFactory objectFactory = new PojoObjectFactory(ctr, null, setters);
            return new SystemAtomicContext(name, objectFactory, eagerInit, init, destroy, stateless);
        }
    }

    public void addTargetWireFactory(String serviceName, TargetWireFactory factory) {
        throw new UnsupportedOperationException();
    }

    public TargetWireFactory getTargetWireFactory(String serviceName) {
        return null;
    }

    public Map<String, TargetWireFactory> getTargetWireFactories() {
        return null;
    }

    public void addSourceWireFactory(String referenceName, SourceWireFactory factory) {
        throw new UnsupportedOperationException();
    }

    public void addSourceWireFactories(String referenceName, Class referenceInterface, List<SourceWireFactory> factory, boolean multiplicity) {

    }

    public List<SourceWireFactory> getSourceWireFactories() {
        return null;
    }

    public void setSetters(List<Injector> setters) {
        this.setters = setters;
    }

    public void setEagerInit(boolean val) {
        eagerInit = val;
    }

    public void setInitInvoker(EventInvoker invoker) {
        init = invoker;
    }

    public void setDestroyInvoker(EventInvoker invoker) {
        destroy = invoker;
    }

    public void prepare(CompositeContext parent) {
        parentContext = parent;
    }

    public CompositeContext getCurrentContext() {
        return parentContext;
    }

}