package com.tobedevoured.modelcitizen; /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF 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. */ import java.util.*; import com.tobedevoured.modelcitizen.callback.Callback; import com.tobedevoured.modelcitizen.callback.internal.Constructable; import com.tobedevoured.modelcitizen.erector.Command; import com.tobedevoured.modelcitizen.field.ModelField; import com.tobedevoured.modelcitizen.template.BlueprintTemplate; import com.tobedevoured.modelcitizen.template.BlueprintTemplateException; import org.apache.commons.lang.builder.ToStringBuilder; /** * Erector for a Class to create an instance from a Blueprint annotated Class */ public class Erector { private static final Set<Command> EMPTY_SET = new HashSet<Command>(); private Object blueprint; private Map<String,ModelField> modelFields; private Map<ModelField,Set<Command>> modelFieldCommands = new HashMap<ModelField,Set<Command>>(); private BlueprintTemplate blueprintTemplate; private Class target; private Constructable newInstance; private Object reference; private Map<String, List<Callback>> callbacks; public Erector() { modelFields = new HashMap<String,ModelField>(); callbacks = new HashMap<String,List<Callback>>(); } /** * Create new instance of {@link Erector#getTarget()}. Uses {@link #getNewInstance()} * if defined, otherwise fails back to {@link BlueprintTemplate#construct} * * @return Object new instance * @throws BlueprintTemplateException */ public Object createNewInstance() throws BlueprintTemplateException { if ( this.getNewInstance() != null ) { // XXX: warn if the return of the callback is not the same class as the target? return this.getNewInstance().createInstance(); } else { return this.getTemplate().construct( this.getTarget() ); } } public void addCommands(ModelField modelField, Set<Command> commands) { for( Command command : commands ) { addCommand( modelField, command ); } } public void addCommand( ModelField modelField, Command command ) { Set<Command> commands = modelFieldCommands.get( modelField ); if ( commands == null ) { commands = new HashSet<Command>(); } commands.add( command ); modelFieldCommands.put( modelField, commands ); } public Set<Command> getCommands( ModelField modelField ) { Set<Command> commands = modelFieldCommands.get( modelField ); if ( commands != null ) { return commands; } else { return EMPTY_SET; } } public void clearCommands() { modelFieldCommands = new HashMap<ModelField,Set<Command>>(); } public Object getBlueprint() { return blueprint; } public void setBlueprint(Object blueprint) { this.blueprint = blueprint; } public Collection<ModelField> getModelFields() { return modelFields.values(); } public ModelField getModelField(String name) { return modelFields.get(name); } public void setModelFields(Collection<ModelField> modelFields) { for( ModelField modelField: modelFields ) { addModelField(modelField); } } public void addModelField(ModelField modelField) { this.modelFields.put(modelField.getName(), modelField); } public BlueprintTemplate getTemplate() { return blueprintTemplate; } public void setTemplate(BlueprintTemplate blueprintTemplate) { this.blueprintTemplate = blueprintTemplate; } public Class getTarget() { return target; } public void setTarget(Class target) { this.target = target; } public Object getReference() { return reference; } public void setReference(Object reference) { this.reference = reference; } public Constructable getNewInstance() { return newInstance; } public void setNewInstance(Constructable newInstance) { this.newInstance = newInstance; } public void setCallbacks(String type, List<Callback> callbacks) { this.callbacks.put(type, callbacks); } public List<Callback> getCallbacks(String type) { return this.callbacks.get(type); } public String toString() { return new ToStringBuilder(this). append("blueprint", blueprint). append("target", target). append("reference", reference). toString(); } }