`ServiceArtifactHandler.java`
`001 /* 002 * Copyright 2009-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.codehaus.griffon.runtime.core; 018 019 import griffon.core.*; 020 import groovy.lang.MetaClass; 021 import groovy.lang.MetaProperty; 022 import org.codehaus.groovy.runtime.InvokerHelper; 023 import org.slf4j.Logger; 024 import org.slf4j.LoggerFactory; 025 026 import java.util.Collections; 027 import java.util.Map; 028 import java.util.concurrent.ConcurrentHashMap; 029 030 import static griffon.util.ConfigUtils.getConfigValueAsBoolean; 031 032 /** 033 * Handler for 'Service' artifacts. 034 * 035 * @author Andres Almiray 036 * @since 0.9.1 037 */ 038 public class ServiceArtifactHandler extends ArtifactHandlerAdapter { 039 private static final Logger LOG = LoggerFactory.getLogger(ServiceArtifactHandler.class); 040 private final ServiceManager serviceManager; 041 042 private class DefaultServiceManager extends AbstractServiceManager { 043 private final Map<String, GriffonService> serviceInstances = new ConcurrentHashMap<String, GriffonService>(); 044 045 public DefaultServiceManager(GriffonApplication app) { 046 super(app); 047 } 048 049 public Map<String, GriffonService> getServices() { 050 return Collections.unmodifiableMap(serviceInstances); 051 } 052 053 public GriffonService findService(String name) { 054 GriffonService serviceInstance = serviceInstances.get(name); 055 if (serviceInstance == null) { 056 GriffonClass griffonClass = findClassFor(name); 057 if (griffonClass != null) { 058 serviceInstance = instantiateService(griffonClass); 059 serviceInstances.put(name, serviceInstance); 060 } 061 } 062 return serviceInstance; 063 } 064 065 private GriffonService instantiateService(GriffonClass griffonClass) { 066 GriffonService serviceInstance = (GriffonService) griffonClass.newInstance(); 067 InvokerHelper.setProperty(serviceInstance, "app", getApp()); 068 getApp().addApplicationEventListener(serviceInstance); 069 return serviceInstance; 070 } 071 } 072 073 public ServiceArtifactHandler(GriffonApplication app) { 074 super(app, GriffonServiceClass.TYPE, GriffonServiceClass.TRAILING); 075 serviceManager = new DefaultServiceManager(app); 076 if (LOG.isDebugEnabled()) { 077 LOG.debug("Registering " + serviceManager + " as ServiceManager."); 078 } 079 InvokerHelper.setProperty(app, "serviceManager", serviceManager); 080 } 081 082 protected GriffonClass newGriffonClassInstance(Class clazz) { 083 return new DefaultGriffonServiceClass(getApp(), clazz); 084 } 085 086 public void initialize(ArtifactInfo[] artifacts) { 087 super.initialize(artifacts); 088 if (isBasicInjectionDisabled()) return; 089 if (isEagerInstantiationEnabled()) { 090 if (LOG.isDebugEnabled()) { 091 LOG.debug("Instantiating service instances eagerly"); 092 } 093 for (ArtifactInfo artifactInfo : artifacts) { 094 GriffonClass griffonClass = getClassFor(artifactInfo.getClazz()); 095 serviceManager.findService(griffonClass.getPropertyName()); 096 } 097 } 098 getApp().addApplicationEventListener(this); 099 } 100 101 /** 102 * Application event listener.<p> 103 * Lazily injects services instances if {@code app.config.griffon.basic_injection.disable} 104 * is not set to true 105 */ 106 public void onNewInstance(Class klass, String t, Object instance) { 107 if (isBasicInjectionDisabled()) return; 108 MetaClass metaClass = InvokerHelper.getMetaClass(instance); 109 for (MetaProperty property : metaClass.getProperties()) { 110 String propertyName = property.getName(); 111 if (!propertyName.endsWith(getTrailing())) continue; 112 GriffonService serviceInstance = serviceManager.findService(propertyName); 113 114 if (serviceInstance != null) { 115 if (LOG.isDebugEnabled()) { 116 LOG.debug("Injecting service " + serviceInstance + " on " + instance + " using property '" + propertyName + "'"); 117 } 118 InvokerHelper.setProperty(instance, propertyName, serviceInstance); 119 } 120 } 121 } 122 123 private boolean isBasicInjectionDisabled() { 124 return getConfigValueAsBoolean(getApp().getConfig(), "griffon.basic_injection.disable", false); 125 } 126 127 private boolean isEagerInstantiationEnabled() { 128 return getConfigValueAsBoolean(getApp().getConfig(), "griffon.services.eager.instantiation", false); 129 } 130 }`