/*
* Copyright 2015 JBoss, by Red Hat, Inc
*
* Licensed 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.uberfire.ext.properties.editor.server;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.Dependent;
import org.jboss.errai.bus.server.annotations.Service;
import org.uberfire.ext.properties.editor.model.PropertyEditorCategory;
import org.uberfire.ext.properties.editor.model.PropertyEditorFieldInfo;
import org.uberfire.ext.properties.editor.model.PropertyEditorType;
import org.uberfire.ext.properties.editor.service.BeanPropertyEditorBuilderService;
@Service
@Dependent
public class BeanPropertyEditorBuilder implements BeanPropertyEditorBuilderService {
@Override
public PropertyEditorCategory extract(String fqcn) {
return extractOnlyBeanInfo(fqcn);
}
@Override
public PropertyEditorCategory extract(String fqcn,
Object instance) {
return extractBeanInfoAndValues(fqcn,
instance);
}
private PropertyEditorCategory extractOnlyBeanInfo(String fqcn) {
return extractBeanInfoAndValues(fqcn,
null);
}
private PropertyEditorCategory extractBeanInfoAndValues(String fqcn,
Object instance) {
Class targetClass;
try {
targetClass = Class.forName(fqcn);
} catch (Exception e) {
throw new NullBeanException("No bean found for FQCN: " + fqcn);
}
PropertyEditorCategory beanCategory = new PropertyEditorCategory(targetClass.getSimpleName());
extractFieldInformationAndValues(targetClass,
beanCategory,
instance);
return beanCategory;
}
private void extractFieldInformationAndValues(Class targetClass,
PropertyEditorCategory beanCategory,
Object instance) throws ErrorReadingFieldInformationAndValues {
for (Field declaredField : targetClass.getDeclaredFields()) {
PropertyEditorType type = PropertyEditorType.getFromType(declaredField.getType());
if (isAHandledType(type)) {
PropertyEditorFieldInfo field = createPropertyEditorInfo(instance,
declaredField,
type);
if (isACombo(field)) {
generateComboValues(declaredField,
field);
}
beanCategory.withField(field);
}
}
}
private PropertyEditorFieldInfo createPropertyEditorInfo(Object instance,
Field declaredField,
PropertyEditorType type) {
if (needToExtractValues(instance)) {
return new PropertyEditorFieldInfo(declaredField.getName(),
extractFieldValue(instance,
declaredField),
type);
} else {
return new PropertyEditorFieldInfo(declaredField.getName(),
type);
}
}
private boolean needToExtractValues(Object instance) {
return instance != null;
}
private boolean isACombo(PropertyEditorFieldInfo field) {
return field.getType().equals(PropertyEditorType.COMBO);
}
private String extractFieldValue(Object instance,
Field field) {
try {
return extractStringValue(instance,
field);
} catch (IllegalAccessException e) {
throw new ErrorReadingFieldInformationAndValues();
}
}
private String extractStringValue(Object instance,
Field field) throws IllegalAccessException {
field.setAccessible(true);
Object value = field.get(instance);
if (value != null) {
return value.toString();
} else {
return "";
}
}
private void generateComboValues(Field declaredField,
PropertyEditorFieldInfo field) {
List<String> values = new ArrayList<String>();
for (Object constant : declaredField.getType().getEnumConstants()) {
values.add(constant.toString());
}
field.withComboValues(values);
}
public boolean isAHandledType(PropertyEditorType type) {
return type != null;
}
public class NullBeanException extends RuntimeException {
public NullBeanException() {
}
public NullBeanException(String message) {
super(message);
}
}
private class ErrorReadingFieldInformationAndValues extends RuntimeException {
}
}