/*
* 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.runtime.system.persistence.adaptermanager;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Maps;
import org.apache.isis.core.commons.ensure.Assert;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
/**
* A root {@link ObjectAdapter adapter} along with aggregated {@link ObjectAdapter adapters}
* for any of its {@link OneToManyAssociation collection}s that are currently present in
* the {@link AdapterManager map}s.
*
* <p>
* Used for "impact analysis" when persisting transient root objects; all aggregated adapters
* must also be persisted.
*/
public class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
private final ObjectAdapter parentAdapter;
private final RootOid rootAdapterOid;
private final Map<OneToManyAssociation, ObjectAdapter> collectionAdapters = Maps.newLinkedHashMap();
public RootAndCollectionAdapters(
final ObjectAdapter parentAdapter,
final AdapterManager adapterManager) {
Assert.assertNotNull(parentAdapter);
this.rootAdapterOid = (RootOid) parentAdapter.getOid();
this.parentAdapter = parentAdapter;
addCollectionAdapters(adapterManager);
}
public ObjectAdapter getRootAdapter() {
return parentAdapter;
}
/**
* Iterate over the
* {@link #addCollectionAdapter(OneToManyAssociation, ObjectAdapter)
* collection adapter}s (does not include the {@link #getRootAdapter() root
* adapter}.
*/
@Override
public Iterator<ObjectAdapter> iterator() {
return getCollectionAdapters().values().iterator();
}
/**
* Which collections are present?
* @return
*/
public Set<OneToManyAssociation> getCollections() {
return getCollectionAdapters().keySet();
}
/**
* Corresponding adapter for each collection (values).
*
* @see #getCollections()
*/
public ObjectAdapter getCollectionAdapter(final OneToManyAssociation otma) {
return collectionAdapters.get(otma);
}
////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////
private void addCollectionAdapters(AdapterManager objectAdapterLookup) {
for (final OneToManyAssociation otma : parentAdapter.getSpecification().getCollections(Contributed.EXCLUDED)) {
final ParentedCollectionOid collectionOid = new ParentedCollectionOid((RootOid) rootAdapterOid, otma);
final ObjectAdapter collectionAdapter = objectAdapterLookup.getAdapterFor(collectionOid);
if (collectionAdapter != null) {
// collection adapters are lazily created and so there may not be one.
addCollectionAdapter(otma, collectionAdapter);
}
}
}
private void addCollectionAdapter(final OneToManyAssociation otma, final ObjectAdapter collectionAdapter) {
Assert.assertNotNull(otma);
Assert.assertNotNull(collectionAdapter);
collectionAdapters.put(otma, collectionAdapter);
}
private Map<OneToManyAssociation, ObjectAdapter> getCollectionAdapters() {
return Collections.unmodifiableMap(collectionAdapters);
}
}