/* See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Esri Inc. 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 com.esri.gpt.catalog.lucene;
import com.esri.gpt.catalog.discovery.PropertyComparisonType;
import com.esri.gpt.catalog.discovery.IStoreable;
import com.esri.gpt.catalog.discovery.IStoreables;
import com.esri.gpt.catalog.discovery.PropertyMeaning;
import com.esri.gpt.catalog.discovery.PropertyMeaningType;
import com.esri.gpt.catalog.discovery.PropertyMeanings;
import com.esri.gpt.catalog.discovery.PropertyValueType;
import com.esri.gpt.framework.collection.CaseInsensitiveMap;
import com.esri.gpt.framework.collection.StringSet;
import java.util.Collection;
import org.apache.lucene.document.Field;
/**
* Essentially defines the storage schema for documents indexed within Lucene.
*/
public class Storeables implements IStoreables {
/** class variables ========================================================= */
/** Document access control list field (multi-value) = "acl" */
public static final String FIELD_ACL = "acl";
/** Document modification date field name = "datemodified" */
public static final String FIELD_DATEMODIFIED = "dateModified";
/** Document file identifier field name = "fileIdentifier" */
public static final String FIELD_FID = "fileIdentifier";
/** Document SCHEMA = "sys.schema", e.g. http://www.isotc211.org/2005/gmd */
public static final String FIELD_SCHEMA = "sys.schema";
/** Document SCHEMA = "sys.schema.key", e.g. fgdc */
public static final String FIELD_SCHEMA_KEY = "sys.schema.key";
/** Document SITEUUID, parent site uuid = "sys.siteuuid" */
public static final String FIELD_SITEUUID = "sys.siteuuid";
/** Document UUID (primary key) field name = "uuid" */
public static final String FIELD_UUID = "uuid";
/** Document XML = "sys.xml" */
public static final String FIELD_XML = "sys.xml";
/** CSW Brief Response XML = "sys.xml.brief" */
public static final String FIELD_XML_BRIEF = "sys.xml.brief";
/** CSW Summary Response XML = "sys.xml.brief" */
public static final String FIELD_XML_SUMMARY = "sys.xml.summary";
/** instance variables ====================================================== */
private CaseInsensitiveMap<IStoreable> map = new CaseInsensitiveMap<IStoreable>(false);
/** constructors ============================================================ */
/** Default constructor. */
public Storeables() {}
/**
* Constructs with a configured collection of property meanings.
* @param meanings the configured property meanings
*/
public Storeables(PropertyMeanings meanings) {
this(meanings, false);
}
/**
* Constructs with a configured collection of property meanings.
* @param meanings the configured property meanings
* @param systemOnly if true, only configure the system storeables
*/
public Storeables(PropertyMeanings meanings, boolean systemOnly) {
if (systemOnly) {
this.ensure(meanings,Storeables.FIELD_UUID);
this.ensure(meanings,Storeables.FIELD_DATEMODIFIED);
} else {
for (PropertyMeaning meaning: meanings.values()) {
IStoreable storeable = this.connect(meaning);
this.add(storeable);
}
}
}
/** properties ============================================================== */
/** methods ================================================================= */
/**
* Adds a store-able property to the collection.
* <br/>The collection is keyed on IStoreable.name.
* @param storable the store-able property to add.
*/
public void add(IStoreable storable) {
if (storable != null) {
map.put(storable.getName(),storable);
}
}
/**
* Returns the storeables collection (for iteration).
* @return the collection of storeables
*/
public Collection<IStoreable> collection() {
return this.map.values();
}
/**
* Connects a meaning to a store-able property,
* @param meaning the meaning associated with the property to connect
* @return an appropriate store-able (null if none was located);
*/
public IStoreable connect(PropertyMeaning meaning) {
Storeable storable = null;
String fieldName = meaning.getName();
PropertyMeaningType meaningType = meaning.getMeaningType();
PropertyComparisonType comparisonType = meaning.getComparisonType();
PropertyValueType valueType = meaning.getValueType();
if (meaning instanceof PropertyMeaning.AnyText) {
PropertyMeaning.AnyText anyText = (PropertyMeaning.AnyText)meaning;
storable = new AnyTextProperty(fieldName,anyText.getNamesToConsider());
} else if (comparisonType.equals(PropertyComparisonType.ANYTEXT)) {
storable = new AnyTextProperty(fieldName,new StringSet());
} else if (fieldName.equalsIgnoreCase("body")) {
storable = new Storeable(fieldName);
DatastoreField field = new DatastoreField(fieldName,
Field.Store.NO,Field.Index.ANALYZED,Field.TermVector.NO);
storable.getFields().add(field);
} else if (comparisonType.equals(PropertyComparisonType.KEYWORD)) {
storable = new Storeable(fieldName);
storable.setComparisonField(new LowerCaseField(fieldName));
storable.setRetrievalField(new ReferenceField(fieldName+".ref"));
storable.getFields().add(storable.getComparisonField());
storable.getFields().add(storable.getRetrievalField());
} else if (!meaningType.equals(PropertyMeaningType.DATEMODIFIED) &&
valueType.equals(PropertyValueType.TIMESTAMP)) {
storable = new Storeable(fieldName);
storable.setComparisonField(new TimestampField(fieldName));
storable.setTermsField(new TermsField(fieldName+".input"));
storable.getFields().add(storable.getComparisonField());
storable.getFields().add(storable.getTermsField());
storable.setRetrievalField(storable.getComparisonField());
} else if (comparisonType.equals(PropertyComparisonType.VALUE)) {
DatastoreField field = null;
if (valueType.equals(PropertyValueType.DOUBLE)) {
field = new DoubleField(fieldName,DoubleField.DEFAULT_PRECISION);
} else if (valueType.equals(PropertyValueType.GEOMETRY)) {
storable = new GeometryProperty(fieldName);
} else if (valueType.equals(PropertyValueType.TIMEPERIOD)) {
storable = new TimeperiodProperty(fieldName);
} else if (valueType.equals(PropertyValueType.LONG)) {
field = new LongField(fieldName);
} else if (valueType.equals(PropertyValueType.STRING)) {
field = new DatastoreField(fieldName,
Field.Store.YES,Field.Index.NOT_ANALYZED,Field.TermVector.NO);
} else if (valueType.equals(PropertyValueType.TIMESTAMP)) {
field = new TimestampField(fieldName);
} else {
// TODO issue warning here (value type not recognized)
}
if (field != null) {
storable = new Storeable(fieldName);
storable.setComparisonField(field);
storable.setRetrievalField(field);
storable.getFields().add(field);
}
} else if (comparisonType.equals(PropertyComparisonType.TERMS)) {
storable = new Storeable(fieldName);
storable.setTermsField(new TermsField(fieldName));
storable.setComparisonField(new LowerCaseField(fieldName+".lc"));
storable.setRetrievalField(storable.getTermsField());
storable.getFields().add(storable.getTermsField());
storable.getFields().add(storable.getComparisonField());
} else {
// TODO issue warning here (comparison type not recognized)
}
return storable;
}
/**
* Ensures a storeable property within the collection.
* @param propertyMeanings the configured property meanings
* @param meaningName the property meaning name
* @return the storeable property (null if no match was located)
*/
public IStoreable ensure(PropertyMeanings propertyMeanings, String meaningName) {
IStoreable storeable = this.get(meaningName);
if (storeable == null) {
PropertyMeaning meaning = propertyMeanings.get(meaningName);
if (meaning != null) {
storeable = this.connect(meaning);
if (storeable != null) {
this.add(storeable);
}
}
}
return storeable;
}
/**
* Finds a store-able property within the collection.
* @param name the name of the store-able property
* @return the store-able property (null if no match was located)
*/
public IStoreable get(String name) {
return map.get(name);
}
}