use of org.apache.sling.models.annotations.Model in project sling by apache.
the class ModelAdapterFactory method internalCreateModel.
@SuppressWarnings("unchecked")
private <ModelType> Result<ModelType> internalCreateModel(final Object adaptable, final Class<ModelType> requestedType) {
Result<ModelType> result;
ThreadInvocationCounter threadInvocationCounter = invocationCountThreadLocal.get();
if (threadInvocationCounter.isMaximumReached()) {
String msg = String.format("Adapting %s to %s failed, too much recursive invocations (>=%s).", adaptable, requestedType, threadInvocationCounter.maxRecursionDepth);
return new Result<ModelType>(new ModelClassException(msg));
}
threadInvocationCounter.increase();
try {
// check if a different implementation class was registered for this adapter type
ModelClass<ModelType> modelClass = getImplementationTypeForAdapterType(requestedType, adaptable);
if (!modelClass.hasModelAnnotation()) {
String msg = String.format("Provided Adapter class does not have a Model annotation: %s", modelClass.getType());
return new Result<ModelType>(new ModelClassException(msg));
}
boolean isAdaptable = false;
Model modelAnnotation = modelClass.getModelAnnotation();
if (modelAnnotation.cache()) {
Map<Class, Object> adaptableCache = adapterCache.get(adaptable);
if (adaptableCache != null) {
ModelType cachedObject = (ModelType) adaptableCache.get(requestedType);
if (cachedObject != null) {
return new Result<ModelType>(cachedObject);
}
}
}
Class<?>[] declaredAdaptable = modelAnnotation.adaptables();
for (Class<?> clazz : declaredAdaptable) {
if (clazz.isInstance(adaptable)) {
isAdaptable = true;
}
}
if (!isAdaptable) {
String msg = String.format("Adaptables (%s) are not acceptable for the model class: %s", StringUtils.join(declaredAdaptable), modelClass.getType());
return new Result<ModelType>(new InvalidAdaptableException(msg));
} else {
RuntimeException t = validateModel(adaptable, modelClass.getType(), modelAnnotation);
if (t != null) {
return new Result<ModelType>(t);
}
if (modelClass.getType().isInterface()) {
Result<InvocationHandler> handlerResult = createInvocationHandler(adaptable, modelClass);
if (handlerResult.wasSuccessful()) {
ModelType model = (ModelType) Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { modelClass.getType() }, handlerResult.getValue());
if (modelAnnotation.cache()) {
Map<Class, Object> adaptableCache = adapterCache.get(adaptable);
if (adaptableCache == null) {
adaptableCache = new ConcurrentHashMap<Class, Object>(INNER_CACHE_INITIAL_CAPACITY);
adapterCache.put(adaptable, adaptableCache);
}
adaptableCache.put(requestedType, model);
}
result = new Result<ModelType>(model);
} else {
return new Result<ModelType>(handlerResult.getThrowable());
}
} else {
try {
result = createObject(adaptable, modelClass);
if (result.wasSuccessful() && modelAnnotation.cache()) {
Map<Class, Object> adaptableCache = adapterCache.get(adaptable);
if (adaptableCache == null) {
adaptableCache = new ConcurrentHashMap<Class, Object>(INNER_CACHE_INITIAL_CAPACITY);
adapterCache.put(adaptable, adaptableCache);
}
adaptableCache.put(requestedType, result.getValue());
}
} catch (Exception e) {
String msg = String.format("Unable to create model %s", modelClass.getType());
return new Result<ModelType>(new ModelClassException(msg, e));
}
}
}
return result;
} finally {
threadInvocationCounter.decrease();
}
}
use of org.apache.sling.models.annotations.Model in project sling by apache.
the class ModelPackageBundleListener method analyzeClass.
private void analyzeClass(Bundle bundle, String className, List<ServiceRegistration> regs) {
try {
Class<?> implType = bundle.loadClass(className);
Model annotation = implType.getAnnotation(Model.class);
if (annotation != null) {
// get list of adapters from annotation - if not given use annotated class itself
Class<?>[] adapterTypes = annotation.adapters();
if (adapterTypes.length == 0) {
adapterTypes = new Class<?>[] { implType };
} else if (!ArrayUtils.contains(adapterTypes, implType)) {
adapterTypes = (Class<?>[]) ArrayUtils.add(adapterTypes, implType);
}
// register adapter only if given adapters are valid
if (validateAdapterClasses(implType, adapterTypes)) {
if (adapterImplementations.addAll(implType, adapterTypes)) {
ServiceRegistration reg = registerAdapterFactory(adapterTypes, annotation.adaptables(), implType, annotation.condition());
regs.add(reg);
String[] resourceTypes = annotation.resourceType();
for (String resourceType : resourceTypes) {
if (StringUtils.isNotEmpty(resourceType)) {
for (Class<?> adaptable : annotation.adaptables()) {
adapterImplementations.registerModelToResourceType(bundle, resourceType, adaptable, implType);
ExportServlet.ExportedObjectAccessor accessor = null;
if (adaptable == Resource.class) {
accessor = new ExportServlet.ResourceAccessor(implType);
} else if (adaptable == SlingHttpServletRequest.class) {
accessor = new ExportServlet.RequestAccessor(implType);
}
Exporter exporterAnnotation = implType.getAnnotation(Exporter.class);
if (exporterAnnotation != null) {
registerExporter(bundle, implType, resourceType, exporterAnnotation, regs, accessor);
}
Exporters exportersAnnotation = implType.getAnnotation(Exporters.class);
if (exportersAnnotation != null) {
for (Exporter ann : exportersAnnotation.value()) {
registerExporter(bundle, implType, resourceType, ann, regs, accessor);
}
}
}
}
}
}
}
}
} catch (ClassNotFoundException e) {
log.warn("Unable to load class", e);
}
}
Aggregations