use of org.apache.tapestry5.annotations.Service in project tapestry-5 by apache.
the class DefaultModuleDefImpl method addDecoratorDef.
private void addDecoratorDef(Method method) {
Decorate annotation = method.getAnnotation(Decorate.class);
Class serviceInterface = annotation == null ? null : annotation.serviceInterface();
// TODO: methods just named "decorate"
String decoratorId = annotation == null ? stripMethodPrefix(method, DECORATE_METHOD_NAME_PREFIX) : extractId(serviceInterface, annotation.id());
// TODO: Check for duplicates
Class returnType = method.getReturnType();
if (returnType.isPrimitive() || returnType.isArray()) {
throw new RuntimeException(String.format("Method %s is named like a service decorator method, but the return type (%s) is not acceptable (try Object).", InternalUtils.asString(method), method.getReturnType().getCanonicalName()));
}
Set<Class> markers = extractMarkers(method, Decorate.class);
DecoratorDef def = new DecoratorDefImpl(method, extractPatterns(decoratorId, method), extractConstraints(method), proxyFactory, decoratorId, serviceInterface, markers);
decoratorDefs.put(decoratorId, def);
}
use of org.apache.tapestry5.annotations.Service in project tapestry-5 by apache.
the class RegistryImpl method performRegistryStartup.
/**
* It's not unreasonable for an eagerly-loaded service to decide to start a thread, at which
* point we raise issues
* about improper publishing of the Registry instance from the RegistryImpl constructor. Moving
* eager loading of
* services out to its own method should ensure thread safety.
*/
@Override
public void performRegistryStartup() {
if (JDKUtils.JDK_1_5) {
throw new RuntimeException("Your JDK version is too old." + " Tapestry requires Java 1.6 or newer since version 5.4.");
}
eagerLoadLock.lock();
List<EagerLoadServiceProxy> proxies = CollectionFactory.newList();
for (Module m : moduleToServiceDefs.keySet()) m.collectEagerLoadServices(proxies);
for (EagerLoadServiceProxy proxy : proxies) {
proxy.eagerLoadService();
}
for (Runnable startup : startups) {
startup.run();
}
startups.clear();
getService("RegistryStartup", Runnable.class).run();
cleanupThread();
}
use of org.apache.tapestry5.annotations.Service in project tapestry-5 by apache.
the class RegistryImpl method findDecoratorsForService.
@Override
public List<ServiceDecorator> findDecoratorsForService(ServiceDef3 serviceDef) {
lock.check();
assert serviceDef != null;
Logger logger = getServiceLogger(serviceDef.getServiceId());
Orderer<ServiceDecorator> orderer = new Orderer<ServiceDecorator>(logger, true);
for (Module module : moduleToServiceDefs.keySet()) {
Set<DecoratorDef> decoratorDefs = module.findMatchingDecoratorDefs(serviceDef);
if (decoratorDefs.isEmpty())
continue;
ServiceResources resources = new ServiceResourcesImpl(this, module, serviceDef, proxyFactory, logger);
for (DecoratorDef decoratorDef : decoratorDefs) {
ServiceDecorator decorator = decoratorDef.createDecorator(module, resources);
try {
orderer.add(decoratorDef.getDecoratorId(), decorator, decoratorDef.getConstraints());
} catch (IllegalArgumentException e) {
throw new RuntimeException(String.format("Service %s has two different decorators methods named decorate%s in different module classes. " + "You can solve this by renaming one of them and annotating it with @Match(\"%2$s\").", serviceDef.getServiceId(), decoratorDef.getDecoratorId()));
}
}
}
return orderer.getOrdered();
}
use of org.apache.tapestry5.annotations.Service in project tapestry-5 by apache.
the class ModuleImpl method findOrCreate.
/**
* Locates the service proxy for a particular service (from the service definition).
*
* @param def defines the service
* @param eagerLoadProxies collection into which proxies for eager loaded services are added (or null)
* @return the service proxy
*/
private Object findOrCreate(final ServiceDef3 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies) {
final String key = def.getServiceId();
final Invokable create = new Invokable() {
@Override
public Object invoke() {
// In a race condition, two threads may try to create the same service simulatenously.
// The second will block until after the first creates the service.
Object result = services.get(key);
if (result == null) {
result = create(def, eagerLoadProxies);
services.put(key, result);
}
return result;
}
};
Invokable find = new Invokable() {
@Override
public Object invoke() {
Object result = services.get(key);
if (result == null)
result = BARRIER.withWrite(create);
return result;
}
};
return BARRIER.withRead(find);
}
use of org.apache.tapestry5.annotations.Service in project tapestry-5 by apache.
the class ServiceBinderImpl method flush.
protected void flush() {
if (serviceInterface == null)
return;
if (source == null)
source = createObjectCreatorSourceFromImplementationClass();
// Combine service-specific markers with those inherited form the module.
Set<Class> markers = CollectionFactory.newSet(defaultMarkers);
markers.addAll(this.markers);
ServiceDef serviceDef = new ServiceDefImpl(serviceInterface, serviceImplementation, serviceId, markers, scope, eagerLoad, preventDecoration, source);
accumulator.addServiceDef(serviceDef);
clear();
}
Aggregations