Package org.apache.isis.core.metamodel.services.container

Source Code of org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you 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.isis.core.metamodel.services.container;

import java.util.ArrayList;
import java.util.List;

import org.apache.isis.applib.DomainObjectContainer;
import org.apache.isis.applib.PersistFailedException;
import org.apache.isis.applib.RepositoryException;
import org.apache.isis.applib.filter.Filter;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.query.QueryFindAllInstances;
import org.apache.isis.applib.security.RoleMemento;
import org.apache.isis.applib.security.UserMemento;
import org.apache.isis.core.commons.authentication.AuthenticationSession;
import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
import org.apache.isis.core.commons.authentication.AuthenticationSessionProviderAware;
import org.apache.isis.core.commons.ensure.Assert;
import org.apache.isis.core.commons.exceptions.IsisException;
import org.apache.isis.core.metamodel.adapter.DomainObjectServices;
import org.apache.isis.core.metamodel.adapter.DomainObjectServicesAware;
import org.apache.isis.core.metamodel.adapter.LocalizationProvider;
import org.apache.isis.core.metamodel.adapter.LocalizationProviderAware;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.ObjectDirtier;
import org.apache.isis.core.metamodel.adapter.ObjectDirtierAware;
import org.apache.isis.core.metamodel.adapter.ObjectPersistor;
import org.apache.isis.core.metamodel.adapter.ObjectPersistorAware;
import org.apache.isis.core.metamodel.adapter.QuerySubmitter;
import org.apache.isis.core.metamodel.adapter.QuerySubmitterAware;
import org.apache.isis.core.metamodel.adapter.map.AdapterMap;
import org.apache.isis.core.metamodel.adapter.map.AdapterMapAware;
import org.apache.isis.core.metamodel.adapter.oid.AggregatedOid;
import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
import org.apache.isis.core.metamodel.consent.InteractionResult;
import org.apache.isis.core.metamodel.services.container.query.QueryFindByPattern;
import org.apache.isis.core.metamodel.services.container.query.QueryFindByTitle;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.SpecificationLookup;
import org.apache.isis.core.metamodel.spec.SpecificationLookupAware;

public class DomainObjectContainerDefault implements DomainObjectContainer, QuerySubmitterAware, ObjectDirtierAware, DomainObjectServicesAware, ObjectPersistorAware, SpecificationLookupAware, AuthenticationSessionProviderAware, AdapterMapAware, LocalizationProviderAware {

    private ObjectDirtier objectDirtier;
    private ObjectPersistor objectPersistor;
    private QuerySubmitter querySubmitter;
    private SpecificationLookup specificationLookup;
    private DomainObjectServices domainObjectServices;
    private AuthenticationSessionProvider authenticationSessionProvider;
    private AdapterMap adapterMap;
    private LocalizationProvider localizationProvider;

    public DomainObjectContainerDefault() {

    }

    // //////////////////////////////////////////////////////////////////
    // titleOf
    // //////////////////////////////////////////////////////////////////

    @Override
    public String titleOf(final Object domainObject) {
        final ObjectAdapter objectAdapter = adapterMap.adapterFor(domainObject);
        return objectAdapter.getSpecification().getTitle(objectAdapter, localizationProvider.getLocalization());
    }

    // //////////////////////////////////////////////////////////////////
    // newInstance, disposeInstance
    // //////////////////////////////////////////////////////////////////

    /**
     * @see #doCreateTransientInstance(ObjectSpecification)
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> T newTransientInstance(final Class<T> ofClass) {
        final ObjectSpecification spec = getSpecificationLookup().loadSpecification(ofClass);
        // TODO check aggregation is supported
        if (spec.isAggregated()) {
            return newAggregatedInstance(this, ofClass);
        } else {
            final ObjectAdapter adapter = doCreateTransientInstance(spec);
            return (T) adapter.getObject();
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T newAggregatedInstance(final Object parent, final Class<T> ofClass) {
        final ObjectSpecification spec = getSpecificationLookup().loadSpecification(ofClass);
        // TODO check aggregation is supported
        if (!spec.isAggregated()) {
            throw new IsisException("Cannot instantiate an object unless it is marked as Aggregated using the newAggregatedInstance method: " + ofClass); // TODO
                                                                                                                                                          // proper
                                                                                                                                                          // type
        }
        final ObjectAdapter adapter = doCreateAggregatedInstance(spec, parent);
        if (adapter.getOid() instanceof AggregatedOid) {
            return (T) adapter.getObject();
        } else {
            throw new IsisException("Object instatiated but was not given a AggregatedOid: " + ofClass); // TODO
                                                                                                         // proper
                                                                                                         // type
        }
    }

    /**
     * Returns a new instance of the specified class that will have been
     * persisted.
     */
    @Override
    public <T> T newPersistentInstance(final Class<T> ofClass) {
        final T newInstance = newTransientInstance(ofClass);
        persist(newInstance);
        return newInstance;
    }

    /**
     * Returns a new instance of the specified class that has the sane persisted
     * state as the specified object.
     */
    @Override
    public <T> T newInstance(final Class<T> ofClass, final Object object) {
        if (isPersistent(object)) {
            return newPersistentInstance(ofClass);
        } else {
            return newTransientInstance(ofClass);
        }
    }

    /**
     * Factored out as a potential hook method for subclasses.
     */
    protected ObjectAdapter doCreateTransientInstance(final ObjectSpecification spec) {
        return getDomainObjectServices().createTransientInstance(spec);
    }

    private ObjectAdapter doCreateAggregatedInstance(final ObjectSpecification spec, final Object parent) {
        final ObjectAdapter parentAdapter = getAdapterMap().getAdapterFor(parent);
        return getDomainObjectServices().createAggregatedInstance(spec, parentAdapter);
    }

    @Override
    public void remove(final Object persistentObject) {
        if (persistentObject == null) {
            throw new IllegalArgumentException("Must specify a reference for disposing an object");
        }
        final ObjectAdapter adapter = getAdapterMap().getAdapterFor(persistentObject);
        if (!isPersistent(persistentObject)) {
            throw new RepositoryException("Object not persistent: " + adapter);
        }

        getObjectPersistor().remove(adapter);
    }

    @Override
    public void removeIfNotAlready(final Object object) {
        if (!isPersistent(object)) {
            return;
        }
        remove(object);
    }

    // //////////////////////////////////////////////////////////////////
    // resolve, objectChanged
    // //////////////////////////////////////////////////////////////////

    @Override
    public void resolve(final Object parent) {
        getDomainObjectServices().resolve(parent);
    }

    @Override
    public void resolve(final Object parent, final Object field) {
        getDomainObjectServices().resolve(parent, field);
    }

    @Override
    public void objectChanged(final Object object) {
        getObjectDirtier().objectChanged(object);
    }

    // //////////////////////////////////////////////////////////////////
    // flush, commit
    // //////////////////////////////////////////////////////////////////

    @Override
    public boolean flush() {
        return getDomainObjectServices().flush();
    }

    @Override
    public void commit() {
        getDomainObjectServices().commit();
    }

    // //////////////////////////////////////////////////////////////////
    // isValid, validate
    // //////////////////////////////////////////////////////////////////

    @Override
    public boolean isValid(final Object domainObject) {
        return validate(domainObject) == null;
    }

    @Override
    public String validate(final Object domainObject) {
        final ObjectAdapter adapter = getAdapterMap().adapterFor(domainObject);
        final InteractionResult validityResult = adapter.getSpecification().isValidResult(adapter);
        return validityResult.getReason();
    }

    // //////////////////////////////////////////////////////////////////
    // persistence
    // //////////////////////////////////////////////////////////////////

    @Override
    public boolean isPersistent(final Object domainObject) {
        final ObjectAdapter adapter = getAdapterMap().adapterFor(domainObject);
        return adapter.isPersistent();
    }

    @Override
    public void persist(final Object transientObject) {
        final ObjectAdapter adapter = getAdapterMap().getAdapterFor(transientObject);
        // TODO check aggregation is supported
        if (adapter.isAggregated()) {
            return;
        }
        if (isPersistent(transientObject)) {
            throw new PersistFailedException("Object already persistent: " + adapter);
        }
        getObjectPersistor().makePersistent(adapter);
    }

    @Override
    public void persistIfNotAlready(final Object object) {
        if (isPersistent(object)) {
            return;
        }
        persist(object);
    }

    // //////////////////////////////////////////////////////////////////
    // security
    // //////////////////////////////////////////////////////////////////

    @Override
    public UserMemento getUser() {
        final AuthenticationSession session = getAuthenticationSessionProvider().getAuthenticationSession();

        final String name = session.getUserName();
        final List<RoleMemento> roleMementos = asRoleMementos(session.getRoles());

        final UserMemento user = new UserMemento(name, roleMementos);
        return user;
    }

    private List<RoleMemento> asRoleMementos(final List<String> roles) {
        final List<RoleMemento> mementos = new ArrayList<RoleMemento>();
        if (roles != null) {
            for (final String role : roles) {
                mementos.add(new RoleMemento(role));
            }
        }
        return mementos;
    }

    // //////////////////////////////////////////////////////////////////
    // properties
    // //////////////////////////////////////////////////////////////////

    @Override
    public String getProperty(final String name) {
        return getDomainObjectServices().getProperty(name);
    }

    @Override
    public String getProperty(final String name, final String defaultValue) {
        final String value = getProperty(name);
        return value == null ? defaultValue : value;
    }

    @Override
    public List<String> getPropertyNames() {
        return getDomainObjectServices().getPropertyNames();
    }

    // //////////////////////////////////////////////////////////////////
    // info, warn, error messages
    // //////////////////////////////////////////////////////////////////

    @Override
    public void informUser(final String message) {
        getDomainObjectServices().informUser(message);
    }

    @Override
    public void raiseError(final String message) {
        getDomainObjectServices().raiseError(message);
    }

    @Override
    public void warnUser(final String message) {
        getDomainObjectServices().warnUser(message);
    }

    // //////////////////////////////////////////////////////////////////
    // allInstances, allMatches
    // //////////////////////////////////////////////////////////////////

    @Override
    public <T> List<T> allInstances(final Class<T> type) {
        return allMatches(new QueryFindAllInstances<T>(type));
    }

    @Override
    public <T> List<T> allMatches(final Class<T> cls, final Filter<? super T> filter) {
        final List<T> allInstances = allInstances(cls);
        final List<T> filtered = new ArrayList<T>();
        for (final T instance : allInstances) {
            if (filter.accept(instance)) {
                filtered.add(instance);
            }
        }
        return filtered;
    }

    @Override
    public <T> List<T> allMatches(final Class<T> type, final T pattern) {
        Assert.assertTrue("pattern not compatible with type", type.isAssignableFrom(pattern.getClass()));
        return allMatches(new QueryFindByPattern<T>(type, pattern));
    }

    @Override
    public <T> List<T> allMatches(final Class<T> type, final String title) {
        return allMatches(new QueryFindByTitle<T>(type, title));
    }

    @Override
    public <T> List<T> allMatches(final Query<T> query) {
        final List<ObjectAdapter> allMatching = getQuerySubmitter().allMatchingQuery(query);
        return AdapterUtils.unwrap(allMatching);
    }

    // //////////////////////////////////////////////////////////////////
    // firstMatch
    // //////////////////////////////////////////////////////////////////

    @Override
    public <T> T firstMatch(final Class<T> cls, final Filter<T> filter) {
        final List<T> allInstances = allInstances(cls);
        for (final T instance : allInstances) {
            if (filter.accept(instance)) {
                return instance;
            }
        }
        return null;
    }

    @Override
    public <T> T firstMatch(final Class<T> type, final T pattern) {
        final List<T> instances = allMatches(type, pattern);
        return firstInstanceElseNull(instances);
    }

    @Override
    public <T> T firstMatch(final Class<T> type, final String title) {
        final List<T> instances = allMatches(type, title);
        return firstInstanceElseNull(instances);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T firstMatch(final Query<T> query) {
        final ObjectAdapter firstMatching = getQuerySubmitter().firstMatchingQuery(query);
        return (T) AdapterUtils.unwrap(firstMatching);
    }

    // //////////////////////////////////////////////////////////////////
    // uniqueMatch
    // //////////////////////////////////////////////////////////////////

    @Override
    public <T> T uniqueMatch(final Class<T> type, final Filter<T> filter) {
        final List<T> instances = allMatches(type, filter);
        if (instances.size() > 1) {
            throw new RepositoryException("Found more than one instance of " + type + " matching filter " + filter);
        }
        return firstInstanceElseNull(instances);
    }

    @Override
    public <T> T uniqueMatch(final Class<T> type, final T pattern) {
        final List<T> instances = allMatches(type, pattern);
        if (instances.size() > 1) {
            throw new RepositoryException("Found more that one instance of " + type + " matching pattern " + pattern);
        }
        return firstInstanceElseNull(instances);
    }

    @Override
    public <T> T uniqueMatch(final Class<T> type, final String title) {
        final List<T> instances = allMatches(type, title);
        if (instances.size() > 1) {
            throw new RepositoryException("Found more that one instance of " + type + " with title " + title);
        }
        return firstInstanceElseNull(instances);
    }

    @Override
    public <T> T uniqueMatch(final Query<T> query) {
        final List<T> instances = allMatches(query);
        if (instances.size() > 1) {
            throw new RepositoryException("Found more that one instance for query:" + query.getDescription());
        }
        return firstInstanceElseNull(instances);
    }

    private <T> T firstInstanceElseNull(final List<T> instances) {
        return instances.size() == 0 ? null : instances.get(0);
    }

    // //////////////////////////////////////////////////////////////////
    // Dependencies
    // //////////////////////////////////////////////////////////////////

    protected QuerySubmitter getQuerySubmitter() {
        return querySubmitter;
    }

    @Override
    public void setQuerySubmitter(final QuerySubmitter querySubmitter) {
        this.querySubmitter = querySubmitter;
    }

    protected DomainObjectServices getDomainObjectServices() {
        return domainObjectServices;
    }

    @Override
    public void setDomainObjectServices(final DomainObjectServices domainObjectServices) {
        this.domainObjectServices = domainObjectServices;
    }

    protected SpecificationLookup getSpecificationLookup() {
        return specificationLookup;
    }

    @Override
    public void setSpecificationLookup(final SpecificationLookup specificationLookup) {
        this.specificationLookup = specificationLookup;
    }

    protected AuthenticationSessionProvider getAuthenticationSessionProvider() {
        return authenticationSessionProvider;
    }

    @Override
    public void setAuthenticationSessionProvider(final AuthenticationSessionProvider authenticationSessionProvider) {
        this.authenticationSessionProvider = authenticationSessionProvider;
    }

    protected AdapterMap getAdapterMap() {
        return adapterMap;
    }

    @Override
    public void setAdapterMap(final AdapterMap adapterManager) {
        this.adapterMap = adapterManager;
    }

    protected ObjectDirtier getObjectDirtier() {
        return objectDirtier;
    }

    @Override
    public void setObjectDirtier(final ObjectDirtier objectDirtier) {
        this.objectDirtier = objectDirtier;
    }

    protected ObjectPersistor getObjectPersistor() {
        return objectPersistor;
    }

    @Override
    public void setObjectPersistor(final ObjectPersistor objectPersistor) {
        this.objectPersistor = objectPersistor;
    }

    @Override
    public void setLocalizationProvider(final LocalizationProvider localizationProvider) {
        this.localizationProvider = localizationProvider;
    }

}
TOP

Related Classes of org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.