/* * $URL: https://secure.revolsys.com/svn/open.revolsys.com/GIS/trunk/src/java/com/revolsys/gis/processor/AddDefaultValuesProcess.java $ * $Author: paul.austin@revolsys.com $ * $Date: 2006-04-29 00:28:10Z $ * $Revision: 112 $ * Copyright 2004-2005 Revolution Systems 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 com.revolsys.gis.parallel; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.log4j.Logger; import org.apache.log4j.NDC; import com.revolsys.datatype.DataType; import com.revolsys.io.PathUtil; import com.revolsys.parallel.channel.Channel; import com.revolsys.parallel.process.AbstractInOutProcess; import com.revolsys.record.Record; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.record.schema.RecordDefinitionFactory; public class AddDefaultValuesProcess extends AbstractInOutProcess<Record, Record> { private static final Logger log = Logger.getLogger(AddDefaultValuesProcess.class); private Set<String> excludedFieldNames = new HashSet<>(); private RecordDefinitionFactory recordDefinitionFactory; private String schemaName; private final Map<RecordDefinition, Map<String, Object>> typeDefaultValues = new HashMap<>(); private void addDefaultValues(final Map<String, Object> defaultValues, final RecordDefinition type) { if (PathUtil.getPath(type.getPath()).equals(this.schemaName)) { defaultValues.putAll(type.getDefaultValues()); } } private Map<String, Object> getDefaultValues(final RecordDefinition type) { if (this.schemaName == null) { return type.getDefaultValues(); } else { Map<String, Object> defaultValues = this.typeDefaultValues.get(type); if (defaultValues == null) { defaultValues = new HashMap<>(); addDefaultValues(defaultValues, type); this.typeDefaultValues.put(type, defaultValues); } return defaultValues; } } /** * Get the list of attribute names that will be excluded from having the * default values set. * * @return The names of the attributes to exclude. */ public Set<String> getExcludedFieldNames() { return this.excludedFieldNames; } public RecordDefinitionFactory getRecordDefinitionFactory() { return this.recordDefinitionFactory; } /** * Get the schema name of the type definitions to get the default values from. * * @return The schema name. */ public String getSchemaName() { return this.schemaName; } private void process(final Record record) { final RecordDefinition type = record.getRecordDefinition(); boolean process = true; if (this.schemaName != null) { if (!PathUtil.getPath(type.getPath()).equals(this.schemaName)) { process = false; } } if (process) { processDefaultValues(record, getDefaultValues(type)); } for (int i = 0; i < type.getFieldCount(); i++) { final Object value = record.getValue(i); if (value instanceof Record) { process((Record)value); } } } private void processDefaultValues(final Record record, final Map<String, Object> defaultValues) { for (final Entry<String, Object> defaultValue : defaultValues.entrySet()) { final String key = defaultValue.getKey(); final Object value = defaultValue.getValue(); setDefaultValue(record, key, value); } } @Override protected void run(final Channel<Record> in, final Channel<Record> out) { for (Record record = in.read(); record != null; record = in.read()) { process(record); out.write(record); } } private void setDefaultValue(final Record record, final String key, final Object value) { final int dotIndex = key.indexOf('.'); if (dotIndex == -1) { if (record.getValue(key) == null && !this.excludedFieldNames.contains(key)) { log.info("Adding attribute " + key + "=" + value); record.setValue(key, value); } } else { final String fieldName = key.substring(0, dotIndex); NDC.push(" -> " + fieldName); try { final String subKey = key.substring(dotIndex + 1); final Object attributeValue = record.getValue(fieldName); if (attributeValue == null) { final RecordDefinition type = record.getRecordDefinition(); final int attrIndex = type.getFieldIndex(fieldName); final DataType dataType = type.getFieldType(attrIndex); final Class<?> typeClass = dataType.getJavaClass(); if (typeClass == Record.class) { final RecordDefinition subClass = this.recordDefinitionFactory .getRecordDefinition(dataType.getName()); final Record subObject = subClass.newRecord(); setDefaultValue(subObject, subKey, value); record.setValue(fieldName, subObject); process(subObject); } } else if (attributeValue instanceof Record) { final Record subObject = (Record)attributeValue; setDefaultValue(subObject, subKey, value); } else if (!fieldName.equals(record.getRecordDefinition().getGeometryFieldName())) { log.error("Attribute '" + fieldName + "' must be a Record"); } } finally { NDC.pop(); } } } /** * Set the list of attribute names that will be excluded from having the * default values set. * * @param excludedFieldNames The names of the attributes to exclude. */ public void setExcludedFieldNames(final Set<String> excludedFieldNames) { this.excludedFieldNames = excludedFieldNames; } public void setRecordDefinitionFactory(final RecordDefinitionFactory recordDefinitionFactory) { this.recordDefinitionFactory = recordDefinitionFactory; } /** * Set the schema name of the type definitions to get the default values from. * * @param schemaName The schema name. */ public void setSchemaName(final String schemaName) { this.schemaName = schemaName; } }