/* 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.schema;
import com.esri.gpt.catalog.search.ResourceIdentifier;
import com.esri.gpt.catalog.discovery.IStoreable;
import com.esri.gpt.catalog.discovery.IStoreables;
import com.esri.gpt.catalog.discovery.PropertyMeanings;
import com.esri.gpt.catalog.lucene.Storeables;
import com.esri.gpt.framework.geometry.Envelope;
import com.esri.gpt.framework.util.Val;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
/**
* Stores values that ascribe meaning to a document.
* <p/>
* Most schema parameters are treated in an abstract fashion, their
* associated meaning is unknown. Several parameters are critical for
* publication and meaning is required. The meaning for a parameter is
* specified within the XML defining the schema. Example: <br/>
* <parameter key="identification.title" meaning="title">
*/
public class Meaning {
// class variables =============================================================
/** Logger */
private static Logger LOGGER = Logger.getLogger(Meaning.class.getName());
/** Document abstract = "abstract" */
public static final String MEANINGTYPE_ABSTRACT = "abstract";
/** Content type = "content.type" */
public static final String MEANINGTYPE_CONTENTTYPE = "contentType";
/** Data theme (i.e ISO topic category) = "dataTheme" */
public static final String MEANINGTYPE_DATATHEME = "dataTheme";
/** Bounding envelope east = "envelope.east" */
public static final String MEANINGTYPE_ENVELOPE_EAST = "envelope.east";
/** Bounding envelope north = "envelope.north" */
public static final String MEANINGTYPE_ENVELOPE_NORTH = "envelope.north";
/** Bounding envelope south = "envelope.south" */
public static final String MEANINGTYPE_ENVELOPE_SOUTH = "envelope.south";
/** Bounding envelope west = "envelope.west" */
public static final String MEANINGTYPE_ENVELOPE_WEST = "envelope.west";
/** ESRI tag document identifier = "esriDocID" */
public static final String MEANINGTYPE_ESRIDOCID = "esriDocID";
/** File identifier = "fileIdentifier" */
public static final String MEANINGTYPE_FILEIDENTIFIER = "fileIdentifier";
/** No meaning = "none" (this is the default) */
public static final String MEANINGTYPE_NONE = "none";
/** Resource type = "resource.type" */
public static final String MEANINGTYPE_RESOURCE_TYPE = "resource.type";
/** Resource URL = "resource.url" */
public static final String MEANINGTYPE_RESOURCE_URL = "resource.url";
/** Thumbnail binary = "thumbnail.binary" */
public static final String MEANINGTYPE_THUMBNAIL_BINARY = "thumbnail.binary";
/** Thumbnail URL = "thumbnail.url" */
public static final String MEANINGTYPE_THUMBNAIL_URL = "thumbnail.url";
/** Document title = "title" */
public static final String MEANINGTYPE_TITLE = "title";
/** original title */
public static final String MEANINGTYPE_TITLE_ORG = "title.org";
/** Website URL = "website.url" */
public static final String MEANINGTYPE_WEBSITE_URL = "website.url";
// instance variables ==========================================================
private String _aimsContentType = "";
private Envelope _envelope = new Envelope();
private String _esriDocID = "";
private PropertyMeanings _propertyMeanings;
private ResourceIdentifier _resourceIdentifier;
private String _resourceType = "";
private IStoreables _storables = new Storeables();
private String _thumbnailBinary = null;
// constructors ================================================================
/**
* Construct with a configured collection of property meanings.
* propertyMeanings the configured property meanings
*/
protected Meaning(PropertyMeanings propertyMeanings) {
this._propertyMeanings = propertyMeanings;
_resourceIdentifier = ResourceIdentifier.newIdentifier(null);
//System.err.println(propertyMeanings);
_storables = new Storeables(this._propertyMeanings);
IStoreable storeable = _storables.get("geometry");
if (storeable != null) {
storeable.setValue(_envelope);
}
}
// properties ==================================================================
/**
* Gets the ArcIMS content type.
* @return the ArcIMS content type
*/
public String getArcIMSContentType() {
return getFirstStoreableValue(Meaning.MEANINGTYPE_CONTENTTYPE);
}
/**
* Sets the ArcIMS content type.
* @param type the ArcIMS content type
*/
public void setArcIMSContentType(String type) {
type = Val.chkStr(type);
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_CONTENTTYPE);
if (storeable != null) storeable.setValue(type);
}
/**
* Gets the bounding envelope.
* @return the bounding envelope
*/
public Envelope getEnvelope() {
return _envelope;
}
/**
* Gets the value the ESRI tagged document UUID.
* <br/>The underlying value is associated with a special ESRI tag used by
* ArcCatalog to uniquely identify the document.
* @return the ESRI tagged document UUID
*/
public String getEsriDocID() {
return _esriDocID;
}
/**
* Sets the value the ESRI tagged document UUID.
* <br/>The underlying value is associated with a special ESRI tag used by
* ArcCatalog to uniquely identify the document.
* @param id the ESRI tagged document UUID
*/
public void setEsriDocID(String id) {
_esriDocID = Val.chkStr(id);
}
/**
* Gets the file identifier.
* <br/>The file identifier is typically associated with ISO-19139 documents.
* @return the file identifier
*/
public String getFileIdentifier() {
return getFirstStoreableValue(Meaning.MEANINGTYPE_FILEIDENTIFIER);
}
/**
* Sets the file identifier.
* <br/>The file identifier is typically associated with ISO-19139 documents.
* @param identifier the file identifier
*/
public void setFileIdentifier(String identifier) {
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_FILEIDENTIFIER);
if (storeable != null) storeable.setValue(identifier);
}
/**
* Gets the configured property meanings.
* @return the property meanings
*/
public PropertyMeanings getPropertyMeanings() {
return this._propertyMeanings;
}
/**
* Gets the resource identifier.
* @return the resource identifier
*/
private ResourceIdentifier getResourceIdentifier() {
return _resourceIdentifier;
}
/**
* Gets the resource type.
* @return the resource type
*/
private String getResourceType() {
return _resourceType;
}
/**
* Sets the resource type.
* @param resourceType the resource type
*/
private void setResourceType(String resourceType) {
_resourceType = Val.chkStr(resourceType);
}
/**
* Gets the resource url.
* @return the resource url
*/
public String getResourceUrl() {
return getFirstStoreableValue(Meaning.MEANINGTYPE_RESOURCE_URL);
}
/**
* Gets store-able properties associated with the eveluated schema.
* @return the store-able properties
*/
public IStoreables getStoreables() {
return this._storables;
}
/**
* Gets the base64 encoded string for the thumbnail image.
* @return the base64 encoded string for the thumbnail image
*/
public String getThumbnailBinary() {
return _thumbnailBinary;
}
/**
* Sets the base64 encoded string for the thumbnail image.
* @param base64 the base64 encoded string for the thumbnail image
*/
public void setThumbnailBinary(String base64) {
_thumbnailBinary = base64;
}
/**
* Gets the thumbnail url.
* @return the thumbnail url
*/
public String getThumbnailUrl() {
return getFirstStoreableValue(Meaning.MEANINGTYPE_THUMBNAIL_URL);
}
/**
* Sets the thumbnail URL.
* @param url the thumbnail URL
*/
public void setThumbnailUrl(String url) {
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_THUMBNAIL_URL);
if (storeable != null) storeable.setValue(url);
}
/**
* Gets the title.
* @return the title
*/
public String getTitle() {
return getFirstStoreableValue(Meaning.MEANINGTYPE_TITLE);
}
/**
* Sets the title.
* @param title the title
*/
public void setTitle(String title) {
title = Val.chkStr(title);
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_TITLE);
if (storeable != null) storeable.setValue(title);
}
/**
* Gets the website url.
* @return the website url
*/
public String getWebsiteUrl() {
return getFirstStoreableValue(Meaning.MEANINGTYPE_WEBSITE_URL);
}
// methods =====================================================================
/**
* Applies meaning associated with evaluated ESRI tags
* @param schema the schema to which evaluated meanings will be applied
* @param esriTags the evaluated ESRI tags
*/
protected void applyEsriTags(Schema schema, EsriTags esriTags) {
// published doc id
if (esriTags != null) {
String sEsriDocID = this.getEsriDocID();
if ((sEsriDocID == null) || (sEsriDocID.length() == 0)) {
sEsriDocID = esriTags.getPublishedDocId();
if ((sEsriDocID != null) && (sEsriDocID.length() > 0)) {
this.setEsriDocID(sEsriDocID);
}
}
}
// thumbnail attachment (base64)
if (esriTags != null) {
String sBase64Thumbnail = this.getThumbnailBinary();
if ((sBase64Thumbnail == null) || (sBase64Thumbnail.length() == 0)) {
sBase64Thumbnail = esriTags.getThumbnailBinary();
if ((sBase64Thumbnail != null) && (sBase64Thumbnail.length() > 0)) {
this.setThumbnailBinary(sBase64Thumbnail);
}
}
}
// website URL
String sWebsiteUrl = getWebsiteUrl();
if ((sWebsiteUrl == null) || (sWebsiteUrl.length() == 0)) {
if (esriTags.getPrimaryOnlink().length() > 0) {
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_WEBSITE_URL);
if (storeable != null) {
storeable.setValue(esriTags.getPrimaryOnlink());
}
}
}
// resource URL
String sResourceUrl = getResourceUrl();
//if ((sResourceUrl == null) || (sResourceUrl.length() == 0)) {
sResourceUrl = Meaning.makeResourceUrl(esriTags,this);
if (sResourceUrl.length() > 0) {
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_RESOURCE_URL);
if (storeable != null) {
storeable.setValue(sResourceUrl);
try {
for (Section section : schema.getSections().values()) {
for (Parameter param : section.getParameters().values()) {
if (param.getMeaningType().equalsIgnoreCase(Meaning.MEANINGTYPE_RESOURCE_URL)) {
if ((param.getContent() != null) && (param.getContent().getSingleValue() != null)) {
//String sCurrent = param.getContent().getSingleValue().getValue();
//if ((sCurrent == null) || (sCurrent.length() == 0)) {
param.getContent().getSingleValue().setValue(sResourceUrl);
//}
}
}
}
}
} catch (Exception e) {}
}
}
//}
}
/**
* Appends property information for the component to a StringBuffer.
* <br/>The method is intended to support "FINEST" logging.
* <br/>super.echo should be invoked prior appending any local information.
* @param sb the StringBuffer to use when appending information
*/
public void echo(StringBuffer sb) {
sb.append(" title=").append(getTitle());
if (getEsriDocID().length() > 0) {
sb.append("\n esriDocID=").append(getEsriDocID());
}
if (getFileIdentifier().length() > 0) {
sb.append("\n fileIdentifier=").append(getFileIdentifier());
}
sb.append("\n envelope:");
sb.append(" west=").append(getEnvelope().getMinX());
sb.append(" south=").append(getEnvelope().getMinY());
sb.append(" east=").append(getEnvelope().getMaxX());
sb.append(" north=").append(getEnvelope().getMaxY());
if (getResourceType().length() > 0) {
sb.append("\n resourceType=").append(getResourceType());
}
if (getResourceUrl().length() > 0) {
sb.append("\n resourceUrl=").append(this.getResourceUrl());
}
if (getThumbnailUrl().length() > 0) {
sb.append("\n thumbnailUrl=").append(this.getThumbnailUrl());
}
if (getWebsiteUrl().length() > 0) {
sb.append("\n websiteUrl=").append(this.getWebsiteUrl());
}
if (getArcIMSContentType().length() > 0) {
sb.append("\n aimsContentType=\"").append(getArcIMSContentType()).append("\"");
}
//sb.append("\n abstract=\n").append(getAbstract());
//sb.append("\n thumbnailBinary=\n").append(getThumbnailBinary());
}
/**
* Evaluates a parameter's meaning.
* @param parameter the subject parameter
*/
public void evaluate(Parameter parameter) {
String sValue = parameter.getContent().getSingleValue().getValue();
String sMeaningType = parameter.getMeaningType();
if (sMeaningType.equals("")) {
// handle the envelope parts
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_EAST)) {
getEnvelope().setMaxX(sValue);
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_NORTH)) {
getEnvelope().setMaxY(sValue);
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_SOUTH)) {
getEnvelope().setMinY(sValue);
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ENVELOPE_WEST)) {
getEnvelope().setMinX(sValue);
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_ESRIDOCID)) {
setEsriDocID(sValue);
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_RESOURCE_TYPE)) {
setResourceType(sValue);
if (getArcIMSContentType().length() == 0) {
setArcIMSContentType(
getResourceIdentifier().guessArcIMSContentTypeFromResourceType(getResourceType()));
}
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_RESOURCE_URL)) {
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_RESOURCE_URL);
if (storeable != null) {
storeable.setValues(parameter.getContent().toValueArray());
if (getArcIMSContentType().length() == 0) {
setArcIMSContentType(
getResourceIdentifier().guessArcIMSContentTypeFromUrl(getResourceUrl()));
}
}
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_DATATHEME)) {
IStoreable storeable = this._storables.get(Meaning.MEANINGTYPE_DATATHEME);
if (storeable != null) {
String[] values = parameter.getContent().toValueArray();
if ((values != null) && (values.length > 0)) {
Map<String,String> map = makeEsriDataThemeCodes();
ArrayList<String> al = new ArrayList<String>();
for (String value: values) {
String s = map.get(value);
if (s != null) al.add(s);
else al.add(value);
}
storeable.setValues(al.toArray(new String[0]));
}
}
} else if (sMeaningType.equalsIgnoreCase(Meaning.MEANINGTYPE_THUMBNAIL_BINARY)) {
_thumbnailBinary = sValue;
// handle the generic case
} else {
IStoreable storeable = this._storables.get(sMeaningType);
if (storeable == null) {
// TODO log a warning
} else {
// TODO need type checking
String[] values = parameter.getContent().toValueArray();
if ((values != null) && (values.length > 0)) {
Object[] existingValues = storeable.getValues();
if ((existingValues != null) && (existingValues.length > 0)) {
java.util.ArrayList<Object> alValues = new ArrayList<Object>();
for (Object value: existingValues) alValues.add(value);
for (String value: values) alValues.add(value);
storeable.setValues(alValues.toArray());
} else {
storeable.setValues(values);
}
}
}
}
}
private String getFirstStoreableValue(String name) {
IStoreable storeable = this._storables.get(name);
if (storeable != null) {
Object[] values = storeable.getValues();
if ((values != null) && (values.length > 0) && (values[0] != null)) {
return values[0].toString();
}
}
return "";
}
// ESRI data theme lookup codes
private Map<String,String> makeEsriDataThemeCodes() {
HashMap<String,String> map = new HashMap<String,String>();
map.put("001","farming");
map.put("002","biota");
map.put("003","boundaries");
map.put("004","climatologyMeteorologyAtmosphere");
map.put("005","economy");
map.put("006","elevation");
map.put("007","environment");
map.put("008","geoscientificInformation");
map.put("009","health");
map.put("010","imageryBaseMapsEarthCover");
map.put("011","intelligenceMilitary");
map.put("012","inlandWaters");
map.put("013","location");
map.put("014","oceans");
map.put("015","planningCadastre");
map.put("016","society");
map.put("017","structure");
map.put("018","transportation");
map.put("019","utilitiesCommunication");
return map;
}
/**
* Makes a resource URL from a set of ESRI tyags.
* @param esriTags the set of ESRI tags
* @param meaning meaning
*/
public static String makeResourceUrl(EsriTags esriTags, Meaning meaning) {
// initialize
String sResourceUrl = "";
String sServer = esriTags.getServer();
String sService = esriTags.getService();
String sServiceType = esriTags.getServiceType();
String sServiceParams = esriTags.getServiceParams();
if (sServer.length() > 0) {
// ArcIMS image/feature/metadata services
if (sServiceType.equalsIgnoreCase("image") ||
sServiceType.equalsIgnoreCase("feature") ||
sServiceType.equalsIgnoreCase("metadata")) {
String sEsrimap = "servlet/com.esri.esrimap.Esrimap";
if (sServer.indexOf(sEsrimap) == -1) {
if ((sServer.indexOf("?") == -1) && (sServer.indexOf("&") == -1)) {
if (!sServer.endsWith("/")) sServer += "/";
if (sService.length() > 0) sResourceUrl = sServer+sEsrimap+"?ServiceName="+sService;
}
} else {
if ((sServer.indexOf("?") == -1) && (sServer.indexOf("&") == -1)) {
if (!sServer.endsWith("/")) sServer += "/";
if (sService.length() > 0) sResourceUrl = sServer+"?ServiceName="+sService;
} else if (sServer.indexOf("ServiceName=") == -1) {
if (sServer.indexOf("?") == -1) {
if (!sServer.endsWith("/")) sServer += "/";
sResourceUrl = sServer+"?ServiceName="+sService;
} else {
sResourceUrl = sServer+"&ServiceName="+sService;
}
}
}
if (sResourceUrl.length() > 0) {
if (sServiceType.equalsIgnoreCase("image")) {
if (meaning != null) meaning.setArcIMSContentType("liveData");
} else if (sServiceType.equalsIgnoreCase("feature")) {
//if (meaning != null) meaning.setArcIMSContentType("liveData");
sResourceUrl = "";
} else if (sServiceType.equalsIgnoreCase("metadata")) {
//if (meaning != null) meaning.setArcIMSContentType("liveData");
sResourceUrl = "";
}
}
// OGC services
} else {
if ((sServer.indexOf("?") == -1) && (sServer.indexOf("&") == -1)) {
if (sServiceParams.length() > 0) {
if (!sServiceParams.startsWith("?")) sServer += "?";
sServer += sServiceParams;
}
}
String sContentType = ResourceIdentifier.newIdentifier(null).guessArcIMSContentTypeFromUrl(sServer);
if ((sContentType.length() > 0) && !sContentType.equalsIgnoreCase("unknown")) {
if (meaning != null) meaning.setArcIMSContentType(sContentType);
sResourceUrl = sServer;
}
}
}
return sResourceUrl;
}
}