org.apache.cayenne.reflect.ClassDescriptorMap Maven / Gradle / Ivy
/*****************************************************************
* 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.cayenne.reflect;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.map.EntityResolver;
/**
* An object that holds class descriptors for mapped entities, compiling new descriptors
* on demand using an internal chain of descriptor factories. Note that the object is ot
* synchronized internally, so it has to be prefilled with descriptors by the caller on
* initialization via calling 'getDescriptor' for all mapped entities.
*
* @since 3.0
*/
public class ClassDescriptorMap {
protected EntityResolver resolver;
protected Map descriptors;
protected List factories;
public ClassDescriptorMap(EntityResolver resolver) {
this.descriptors = new HashMap();
this.resolver = resolver;
this.factories = new ArrayList();
}
public EntityResolver getResolver() {
return resolver;
}
/**
* Adds a factory to the descriptor factory chain.
*/
public void addFactory(ClassDescriptorFactory factory) {
factories.add(factory);
}
public void removeFactory(ClassDescriptorFactory factory) {
factories.remove(factory);
}
public void clearFactories() {
factories.clear();
}
public void clearDescriptors() {
descriptors.clear();
}
/**
* Removes cached descriptor if any for the given entity.
*/
public void removeDescriptor(String entityName) {
descriptors.remove(entityName);
}
/**
* Caches descriptor definition.
*/
public void addDescriptor(String entityName, ClassDescriptor descriptor) {
if (descriptor == null) {
removeDescriptor(entityName);
}
else {
descriptors.put(entityName, descriptor);
}
}
public ClassDescriptor getDescriptor(String entityName) {
if (entityName == null) {
throw new NullPointerException("Null 'entityName'");
}
ClassDescriptor cached = descriptors.get(entityName);
if (cached != null) {
return cached;
}
return createProxyDescriptor(entityName);
}
/**
* Creates a descriptor wrapper that will compile the underlying descriptor on demand.
* Using proxy indirection is needed to compile relationships of descriptors to other
* descriptors that are not compiled yet.
*/
protected ClassDescriptor createProxyDescriptor(String entityName) {
ClassDescriptor descriptor = new LazyClassDescriptorDecorator(this, entityName);
addDescriptor(entityName, descriptor);
return descriptor;
}
/**
* Creates a new descriptor.
*/
protected ClassDescriptor createDescriptor(String entityName) {
// scan the factory chain until some factory returns a non-null descriptor;
// scanning is done in reverse order so that the factories added last take higher
// precedence...
ListIterator it = factories
.listIterator(factories.size());
while (it.hasPrevious()) {
ClassDescriptorFactory factory = it.previous();
ClassDescriptor descriptor = factory.getDescriptor(entityName);
if (descriptor != null) {
return descriptor;
}
}
throw new CayenneRuntimeException("Failed to create descriptor for entity: "
+ entityName);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy