/** * Licensed to the Austrian Association for Software Tool Integration (AASTI) * under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright * ownership. The AASTI licenses this file to you 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.openengsb.core.ekb.common; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.reflect.FieldUtils; import org.openengsb.core.api.model.ModelDescription; import org.openengsb.core.api.model.OpenEngSBModel; import org.openengsb.core.api.model.annotation.OpenEngSBForeignKey; import org.openengsb.core.edb.api.EngineeringDatabaseService; import org.openengsb.core.ekb.api.EKBException; import org.openengsb.core.ekb.api.ModelRegistry; /** * The EngineeringObjectModelWrapper class is a helper class which encapsulates functions for models which are * Engineering Objects. */ public final class EngineeringObjectModelWrapper extends AdvancedModelWrapper { private EngineeringObjectModelWrapper(OpenEngSBModel model) { super(model); } /** * Returns the corresponding engineering object model wrapper to the given advanced model wrapper. */ public static EngineeringObjectModelWrapper enhance(AdvancedModelWrapper model) { if (!model.isEngineeringObject()) { throw new IllegalArgumentException("The model of the AdvancedModelWrapper is no EngineeringObject"); } return new EngineeringObjectModelWrapper(model.getUnderlyingModel()); } /** * Returns a list of foreign key fields for the Engineering Object model. */ public List<Field> getForeignKeyFields() { List<Field> fields = new ArrayList<Field>(); for (Field field : model.getClass().getDeclaredFields()) { if (field.isAnnotationPresent(OpenEngSBForeignKey.class)) { fields.add(field); } } return fields; } /** * Loads the model referenced by the given field for the given model instance. Returns null if the field has no * value set. */ public AdvancedModelWrapper loadReferencedModel(Field field, ModelRegistry modelRegistry, EngineeringDatabaseService edbService, EDBConverter edbConverter) { try { ModelDescription description = getModelDescriptionFromField(field); String modelKey = (String) FieldUtils.readField(field, model, true); if (modelKey == null) { return null; } modelKey = appendContextId(modelKey); Class<?> sourceClass = modelRegistry.loadModel(description); Object model = edbConverter.convertEDBObjectToModel(sourceClass, edbService.getObject(modelKey)); return new AdvancedModelWrapper((OpenEngSBModel) model); } catch (SecurityException e) { throw new EKBException(generateErrorMessage(field), e); } catch (IllegalArgumentException e) { throw new EKBException(generateErrorMessage(field), e); } catch (IllegalAccessException e) { throw new EKBException(generateErrorMessage(field), e); } catch (ClassNotFoundException e) { throw new EKBException(generateErrorMessage(field), e); } } /** * Generates the error message for the failure of loading a model reference. */ private String generateErrorMessage(Field field) { return String.format("Unable to load the model referenced through the field %s", field.getName()); } /** * Generates the model description of a field which is annotated with the OpenEngSBForeignKey annotation. */ private ModelDescription getModelDescriptionFromField(Field field) { OpenEngSBForeignKey key = field.getAnnotation(OpenEngSBForeignKey.class); ModelDescription description = new ModelDescription(key.modelType(), key.modelVersion()); return description; } }