001 /*
002 * Copyright 2010-2013 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.resources;
018
019 import griffon.core.GriffonApplication;
020 import griffon.core.resources.InjectedResource;
021 import griffon.core.resources.ResourcesInjector;
022 import org.slf4j.Logger;
023 import org.slf4j.LoggerFactory;
024
025 import java.beans.PropertyEditor;
026 import java.beans.PropertyEditorManager;
027 import java.lang.reflect.Field;
028 import java.util.Arrays;
029
030 import static griffon.util.GriffonExceptionHandler.sanitize;
031 import static griffon.util.GriffonNameUtils.isBlank;
032
033 /**
034 * @author Andres Almiray
035 * @since 1.2.0
036 */
037 public abstract class AbstractResourcesInjector implements ResourcesInjector {
038 private static final Logger LOG = LoggerFactory.getLogger(AbstractResourcesInjector.class);
039 private final GriffonApplication app;
040
041 public AbstractResourcesInjector(GriffonApplication app) {
042 this.app = app;
043 }
044
045 public GriffonApplication getApp() {
046 return app;
047 }
048
049 @Override
050 public void injectResources(Object instance) {
051 if (null == instance) return;
052 Class klass = instance.getClass();
053 do {
054 doResourceInjection(klass, instance);
055 klass = klass.getSuperclass();
056 } while (null != klass);
057 }
058
059 protected boolean doResourceInjection(Class klass, Object instance) {
060 boolean injected = false;
061 for (Field field : klass.getDeclaredFields()) {
062 if (field.isSynthetic()) continue;
063 final InjectedResource annotation = field.getAnnotation(InjectedResource.class);
064 if (null == annotation) continue;
065
066 String fqFieldName = field.getDeclaringClass().getName().replace('$', '.') + "." + field.getName();
067 String key = annotation.key();
068 String[] args = annotation.args();
069 String defaultValue = annotation.defaultValue();
070 if (isBlank(key)) key = fqFieldName;
071
072 if (LOG.isDebugEnabled()) {
073 LOG.debug("Field " + fqFieldName +
074 " of instance " + instance +
075 " [key='" + key +
076 "', args='" + Arrays.toString(args) +
077 "', defaultValue='" + defaultValue +
078 "'] is marked for resource injection.");
079 }
080
081 Object value = null;
082 if (isBlank(defaultValue)) {
083 value = resolveResource(key, args);
084 } else {
085 value = resolveResource(key, args, defaultValue);
086 }
087
088 if (null != value) {
089 if (!field.getType().isAssignableFrom(value.getClass())) {
090 value = convertValue(field.getType(), value);
091 }
092 setFieldValue(instance, field, value, fqFieldName);
093 }
094 injected = true;
095 }
096 return injected;
097 }
098
099 protected abstract Object resolveResource(String key, String[] args);
100
101 protected abstract Object resolveResource(String key, String[] args, String defaultValue);
102
103 protected Object convertValue(Class<?> type, Object value) {
104 final PropertyEditor propertyEditor = PropertyEditorManager.findEditor(type);
105 if (null == propertyEditor) return value;
106 if (value instanceof CharSequence) {
107 propertyEditor.setAsText(String.valueOf(value));
108 } else {
109 propertyEditor.setValue(value);
110 }
111 return propertyEditor.getValue();
112 }
113
114 protected void setFieldValue(Object instance, Field field, Object value, String fqFieldName) {
115 try {
116 field.setAccessible(true);
117 field.set(instance, value);
118 } catch (IllegalAccessException e) {
119 if (LOG.isWarnEnabled()) {
120 LOG.warn("Cannot set value on field " + fqFieldName + " of instance " + instance, sanitize(e));
121 }
122 }
123 }
124 }
|