001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.metamodel.runtimecontext;
021
022import java.util.Collection;
023import java.util.List;
024import java.util.Properties;
025
026import com.google.common.collect.Lists;
027
028import org.apache.isis.applib.DomainObjectContainer;
029import org.apache.isis.core.metamodel.services.container.DomainObjectContainerAware;
030import org.apache.isis.core.metamodel.spec.ObjectSpecId;
031import org.apache.isis.core.metamodel.spec.ObjectSpecification;
032import org.apache.isis.core.metamodel.spec.SpecificationLoader;
033import org.apache.isis.core.metamodel.spec.SpecificationLoaderDelegator;
034import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
035import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpiAware;
036
037public abstract class RuntimeContextAbstract implements RuntimeContext, SpecificationLoaderSpiAware, DomainObjectContainerAware {
038
039    private final SpecificationLoaderDelegator specificationLookupDelegator = new SpecificationLoaderDelegator();
040    
041    private DomainObjectContainer container;
042    private Properties properties;
043
044
045    @Override
046    public void init() {
047    }
048
049    @Override
050    public void shutdown() {
051    }
052
053
054    @Override
055    public void injectInto(final Object candidate) {
056        if (RuntimeContextAware.class.isAssignableFrom(candidate.getClass())) {
057            final RuntimeContextAware cast = RuntimeContextAware.class.cast(candidate);
058            cast.setRuntimeContext(this);
059        }
060        injectSubcomponentsInto(candidate);
061    }
062
063    protected void injectSubcomponentsInto(final Object candidate) {
064        getAdapterManager().injectInto(candidate);
065        getAuthenticationSessionProvider().injectInto(candidate);
066        getDependencyInjector().injectInto(candidate);
067        getDomainObjectServices().injectInto(candidate);
068        getLocalizationProvider().injectInto(candidate);
069        getObjectInstantiator().injectInto(candidate);
070        getObjectDirtier().injectInto(candidate);
071        getObjectPersistor().injectInto(candidate);
072        getQuerySubmitter().injectInto(candidate);
073        getServicesProvider().injectInto(candidate);
074        getSpecificationLoader().injectInto(candidate);
075    }
076
077    @Override
078    public SpecificationLoader getSpecificationLoader() {
079        return specificationLookupDelegator;
080    }
081
082    /**
083     * Is injected into when the reflector is
084     * {@link ObjectReflectorAbstract#init() initialized}.
085     */
086    @Override
087    public void setSpecificationLoaderSpi(final SpecificationLoaderSpi specificationLoader) {
088        this.specificationLookupDelegator.setDelegate(new SpecificationLoader() {
089
090            @Override
091            public void injectInto(final Object candidate) {
092                specificationLoader.injectInto(candidate);
093            }
094
095            @Override
096            public ObjectSpecification loadSpecification(final Class<?> cls) {
097                return specificationLoader.loadSpecification(cls);
098            }
099
100            @Override
101            public Collection<ObjectSpecification> allSpecifications() {
102                return specificationLoader.allSpecifications();
103            }
104
105            @Override
106            public ObjectSpecification lookupBySpecId(ObjectSpecId objectSpecId) {
107                return specificationLoader.lookupBySpecId(objectSpecId);
108            }
109
110            @Override
111            public ObjectSpecification loadSpecification(String fullyQualifiedClassName) {
112                return specificationLoader.loadSpecification(fullyQualifiedClassName);
113            }
114
115            @Override
116            public boolean loadSpecifications(List<Class<?>> typesToLoad) {
117                return specificationLoader.loadSpecifications(typesToLoad);
118            }
119
120            @Override
121            public boolean loadSpecifications(List<Class<?>> typesToLoad, Class<?> typeToIgnore) {
122                return specificationLoader.loadSpecifications(typesToLoad, typeToIgnore);
123            }
124
125            @Override
126            public boolean loaded(Class<?> cls) {
127                return specificationLoader.loaded(cls);
128            }
129
130            @Override
131            public boolean loaded(String fullyQualifiedClassName) {
132                return specificationLoader.loaded(fullyQualifiedClassName);
133            }
134
135            @Override
136            public ObjectSpecification introspectIfRequired(ObjectSpecification spec) {
137                return specificationLoader.introspectIfRequired(spec);
138            }
139
140            @Override
141            public List<Class<?>> getServiceClasses() {
142                return specificationLoader.getServiceClasses();
143            }
144
145            @Override
146            public void invalidateCache(Class<?> domainClass) {
147                specificationLoader.invalidateCache(domainClass);
148            }
149        });
150    }
151
152    protected DomainObjectContainer getContainer() {
153        return container;
154    }
155
156    /**
157     * So that {@link #injectServicesInto(Object)} can also inject the
158     * {@link DomainObjectContainer}.
159     */
160    @Override
161    public void setContainer(final DomainObjectContainer container) {
162        this.container = container;
163    }
164
165    public void setProperties(final Properties properties) {
166        this.properties = properties;
167    }
168
169    public String getProperty(final String name) {
170        return properties.getProperty(name);
171    }
172
173    public List<String> getPropertyNames() {
174        final List<String> list = Lists.newArrayList();
175        for (final Object key : properties.keySet()) {
176            list.add((String) key);
177        }
178        return list;
179    }
180
181}