/******************************************************************************* * 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. *******************************************************************************/ package org.apache.ofbiz.entity.model; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ofbiz.base.config.GenericConfigException; import org.apache.ofbiz.base.config.MainResourceHandler; import org.apache.ofbiz.base.config.ResourceHandler; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.UtilTimer; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.UtilXml; import org.apache.ofbiz.base.util.cache.UtilCache; import org.apache.ofbiz.entity.GenericEntityConfException; import org.apache.ofbiz.entity.config.model.Datasource; import org.apache.ofbiz.entity.config.model.EntityConfig; import org.apache.ofbiz.entity.config.model.FieldType; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Field Type Definition Reader. * */ @SuppressWarnings("serial") public class ModelFieldTypeReader implements Serializable { public static final String module = ModelFieldTypeReader.class.getName(); protected static final UtilCache<String, ModelFieldTypeReader> readers = UtilCache.createUtilCache("entity.ModelFieldTypeReader", 0, 0); protected static Map<String, ModelFieldType> createFieldTypeCache(Element docElement, String location) { docElement.normalize(); Map<String, ModelFieldType> fieldTypeMap = new HashMap<String, ModelFieldType>(); List<? extends Element> fieldTypeList = UtilXml.childElementList(docElement, "field-type-def"); for (Element curFieldType: fieldTypeList) { String fieldTypeName = curFieldType.getAttribute("type"); if (UtilValidate.isEmpty(fieldTypeName)) { Debug.logError("Invalid field-type element, type attribute is missing in file " + location, module); } else { ModelFieldType fieldType = new ModelFieldType(curFieldType); fieldTypeMap.put(fieldTypeName.intern(), fieldType); } } return fieldTypeMap; } public static ModelFieldTypeReader getModelFieldTypeReader(String helperName) { Datasource datasourceInfo = EntityConfig.getDatasource(helperName); if (datasourceInfo == null) { throw new IllegalArgumentException("Could not find a datasource/helper with the name " + helperName); } String tempModelName = datasourceInfo.getFieldTypeName(); ModelFieldTypeReader reader = readers.get(tempModelName); while (reader == null) { FieldType fieldTypeInfo = null; try { fieldTypeInfo = EntityConfig.getInstance().getFieldType(tempModelName); } catch (GenericEntityConfException e) { Debug.logWarning(e, "Exception thrown while getting field type config: ", module); } if (fieldTypeInfo == null) { throw new IllegalArgumentException("Could not find a field-type definition with name \"" + tempModelName + "\""); } ResourceHandler fieldTypeResourceHandler = new MainResourceHandler(EntityConfig.ENTITY_ENGINE_XML_FILENAME, fieldTypeInfo.getLoader(), fieldTypeInfo.getLocation()); UtilTimer utilTimer = new UtilTimer(); utilTimer.timerString("[ModelFieldTypeReader.getModelFieldTypeReader] Reading field types from " + fieldTypeResourceHandler.getLocation()); Document document = null; try { document = fieldTypeResourceHandler.getDocument(); } catch (GenericConfigException e) { Debug.logError(e, module); throw new IllegalStateException("Error loading field type file " + fieldTypeResourceHandler.getLocation()); } Map<String, ModelFieldType> fieldTypeMap = createFieldTypeCache(document.getDocumentElement(), fieldTypeResourceHandler.getLocation()); reader = readers.putIfAbsentAndGet(tempModelName, new ModelFieldTypeReader(fieldTypeMap)); utilTimer.timerString("[ModelFieldTypeReader.getModelFieldTypeReader] Read " + fieldTypeMap.size() + " field types"); } return reader; } protected final Map<String, ModelFieldType> fieldTypeCache; public ModelFieldTypeReader(Map<String, ModelFieldType> fieldTypeMap) { this.fieldTypeCache = fieldTypeMap; } /** Creates a Collection with all of the ModelFieldType names * @return A Collection of ModelFieldType names */ public Collection<String> getFieldTypeNames() { return this.fieldTypeCache.keySet(); } /** Creates a Collection with all of the ModelFieldTypes * @return A Collection of ModelFieldTypes */ public Collection<ModelFieldType> getFieldTypes() { return this.fieldTypeCache.values(); } /** Gets an FieldType object based on a definition from the specified XML FieldType descriptor file. * @param fieldTypeName The fieldTypeName of the FieldType definition to use. * @return An FieldType object describing the specified fieldType of the specified descriptor file. */ public ModelFieldType getModelFieldType(String fieldTypeName) { return this.fieldTypeCache.get(fieldTypeName); } }