001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.dataformat.bindy;
018
019 import java.lang.reflect.Field;
020 import java.util.HashMap;
021 import java.util.LinkedHashMap;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.Set;
025
026 import org.apache.camel.dataformat.bindy.util.AnnotationModelLoader;
027 import org.apache.camel.spi.PackageScanClassResolver;
028 import org.apache.camel.util.ObjectHelper;
029 import org.apache.commons.logging.Log;
030 import org.apache.commons.logging.LogFactory;
031
032 /**
033 * The BindyAbstractFactory implements what its common to all the
034 * formats supported by camel bindy
035 */
036 public abstract class BindyAbstractFactory implements BindyFactory {
037 private static final transient Log LOG = LogFactory.getLog(BindyAbstractFactory.class);
038 protected Set<Class> models;
039 protected Map<String, Field> mapAnnotedLinkField = new LinkedHashMap<String, Field>();
040 protected String crlf;
041
042 private AnnotationModelLoader modelsLoader;
043
044 private String packageName;
045
046 public BindyAbstractFactory(PackageScanClassResolver resolver, String packageName) throws Exception {
047 this.modelsLoader = new AnnotationModelLoader(resolver);
048 this.packageName = packageName;
049 initModel();
050 }
051
052 /**
053 * method uses to initialize the model representing the classes who will
054 * bind the data. This process will scan for classes according to the package
055 * name provided, check the classes and fields annoted.
056 *
057 * @throws Exception
058 */
059 public void initModel() throws Exception {
060
061 // Find classes defined as Model
062 initModelClasses(packageName);
063
064 }
065
066 /**
067 * Find all the classes defined as model
068 */
069 private void initModelClasses(String packageName) throws Exception {
070 models = modelsLoader.loadModels(packageName);
071 }
072
073 /**
074 * Find fields annoted in each class of the model
075 */
076 public abstract void initAnnotedFields() throws Exception;
077
078 public abstract void bind(List<String> data, Map<String, Object> model) throws Exception;
079
080 public abstract String unbind(Map<String, Object> model) throws Exception;
081
082 /**
083 * Link objects together (Only 1to1 relation is allowed)
084 */
085 public void link(Map<String, Object> model) throws Exception {
086
087 for (String link : mapAnnotedLinkField.keySet()) {
088
089 Field field = mapAnnotedLinkField.get(link);
090 field.setAccessible(true);
091
092 // Retrieve linked object
093 String toClassName = field.getType().getName();
094 Object to = model.get(toClassName);
095
096 ObjectHelper.notNull(to, "No @link annotation has been defined for the oject to link");
097 field.set(model.get(field.getDeclaringClass().getName()), to);
098
099 }
100 }
101
102 /**
103 * Factory method generating new instances of the model and adding them to a
104 * HashMap
105 *
106 * @return Map is a collection of the objects used to bind data from records, messages
107 * @throws Exception can be thrown
108 */
109 public Map<String, Object> factory() throws Exception {
110
111 Map<String, Object> mapModel = new HashMap<String, Object>();
112
113 for (Class<?> cl : models) {
114
115 Object obj = ObjectHelper.newInstance(cl);
116
117 // Add instance of the class to the Map Model
118 mapModel.put(obj.getClass().getName(), obj);
119
120 }
121
122 return mapModel;
123 }
124
125 /**
126 * Find the carriage return set
127 */
128 public String getCarriageReturn() {
129 return crlf;
130 }
131 }