/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * 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 org.constellation.util; import javax.xml.bind.annotation.XmlValue; import java.util.Date; import org.geotoolkit.util.NamesExt; import org.opengis.util.GenericName; /** * Reference to a provider or service layer. * The reference pattern depend of the type of input data. * * If DataReference is from a provider layer, the pattern will be like : * <code>${providerLayerType|providerId|layerId}</code> for example <code>${providerLayerType|shapeFileProvider|CountiesLayer}</code> * use {@link #createProviderDataReference(String, String, String, java.util.Date)} with {@link #PROVIDER_LAYER_TYPE} * * If DataReference is from a provider Style, the pattern will be like : * <code>${providerStyleType|providerId|layerId}</code> for example <code>${providerStyleType|sldProvider|flashyStyle}</code> * use {@link #createProviderDataReference(String, String, String, java.util.Date)} with {@link #PROVIDER_STYLE_TYPE} * * If DataReference is from a Service, the pattern will be like : * <code>${serviceType|serviceURL|serviceSpec|serviceId|layerId}</code> for example <code>${serviceType|http://localhost:8080/cstl/WS/wms/defaultInstance|WMS|defaultInstance|CountiesLayer}</code> * use {@link #createServiceDataReference(String, String, String, String, java.util.Date)} * * Parameter <code>dataVersion</code> add the version used to extract data only if reference data support versionning. * * layer identifier should be with namespace like "{http://geotoolkit.org}myLayer". * * @author Johann Sorel (Geomatys) * @author Quentin Boileau (Geomatys). */ public class DataReference implements CharSequence, Comparable<DataReference>{ private static final String SEPARATOR = "|"; /* * Data types */ public static String PROVIDER_LAYER_TYPE = "providerLayerType"; public static String PROVIDER_STYLE_TYPE = "providerStyleType"; public static String SERVICE_TYPE = "serviceType"; protected String reference; /** * Reference type can be {@link #PROVIDER_LAYER_TYPE} or {@link #PROVIDER_STYLE_TYPE} or {@link #SERVICE_TYPE}. */ protected String type; protected String providerId; protected String serviceURL; protected String serviceSpec; protected String serviceId; protected String layerId; /** * Date version of targed data. In timestamp. */ protected String dataVersion; public DataReference() { this.reference = null; } public DataReference(final String str) { this.reference = str; computeReferenceParts(); } /** * DataReference constructor without layer version date. * @param dataType {@link #PROVIDER_LAYER_TYPE} {@link #PROVIDER_STYLE_TYPE} {@link #SERVICE_TYPE} * @param providerId * @param serviceURL * @param serviceSpec * @param serviceId * @param layerId layer identifier with namespace like "{http://geotoolkit.org}myLayer" */ public DataReference (final String dataType, final String providerId, final String serviceURL, final String serviceSpec, final String serviceId, final String layerId) { this(dataType, providerId, serviceURL, serviceSpec, serviceId, layerId, null); } /** * DataReference constructor WITH layer version date. * @param dataType {@link #PROVIDER_LAYER_TYPE} {@link #PROVIDER_STYLE_TYPE} {@link #SERVICE_TYPE} * @param providerId * @param serviceURL * @param serviceSpec * @param serviceId * @param layerId layer identifier with namespace like "{http://geotoolkit.org}myLayer" * @param dataVersion date of date version. (can be used only if targeted data is versioned). */ public DataReference (final String dataType, final String providerId, final String serviceURL, final String serviceSpec, final String serviceId, final String layerId, final Date dataVersion) { if (dataType != null && (dataType.equals(PROVIDER_LAYER_TYPE) || dataType.equals(PROVIDER_STYLE_TYPE) || dataType.equals(SERVICE_TYPE))) { this.type = dataType; } else { throw new IllegalArgumentException("Reference should match pattern ${providerLayerType|providerId|layerId} or ${providerStyleType|providerId|layerId} or ${serviceType|serviceURL|serviceSpec|serviceId|layerId}."); } this.serviceURL = serviceURL; this.providerId = providerId; this.serviceSpec = serviceSpec; this.serviceId = serviceId; this.layerId = layerId; this.reference = buildRefrenceString(); this.dataVersion = dataVersion != null ? Long.valueOf(dataVersion.getTime()).toString() : null; } /** * Create a DataReference from a provider layer or style. * @param providerType should be {@link #PROVIDER_LAYER_TYPE} or {@link #PROVIDER_STYLE_TYPE} * @param providerId provider identifier * @param layerId layer identifier with namespace like "{http://geotoolkit.org}myLayer" * @return DataReference */ public static DataReference createProviderDataReference(final String providerType, final String providerId, final String layerId) { return createProviderDataReference(providerType, providerId, layerId, null); } /** * Create a DataReference from a provider layer or style. * @param providerType should be {@link #PROVIDER_LAYER_TYPE} or {@link #PROVIDER_STYLE_TYPE} * @param providerId provider identifier * @param layerId layer identifier with namespace like "{http://geotoolkit.org}myLayer" * @param dataVersion Date of data version. * @return DataReference */ public static DataReference createProviderDataReference(final String providerType, final String providerId, final String layerId, final Date dataVersion) { if (providerType != null && (providerType.equals(PROVIDER_LAYER_TYPE) || providerType.equals(PROVIDER_STYLE_TYPE))) { return new DataReference(providerType, providerId, null, null, null, layerId, dataVersion); } throw new IllegalArgumentException("Reference should match pattern ${providerLayerType|providerId|layerId} or ${providerStyleType|providerId|layerId}."); } /** * Create a DataReference from a service. * @param serviceSpec like WMS, WFS, ... * @param serviceId instance identifier of the service * @param layerId layer identifier with namespace like "{http://geotoolkit.org}myLayer" * @return DataReference */ public static DataReference createServiceDataReference(final String serviceURL, final String serviceSpec, final String serviceId, final String layerId) { return createServiceDataReference(serviceURL, serviceSpec, serviceId, layerId, null); } /** * Create a DataReference from a service. * @param serviceSpec like WMS, WFS, ... * @param serviceId instance identifier of the service * @param layerId layer identifier with namespace like "{http://geotoolkit.org}myLayer" * @param dataVersion Date of data version. * @return DataReference */ public static DataReference createServiceDataReference(final String serviceURL, final String serviceSpec, final String serviceId, final String layerId, final Date dataVersion) { return new DataReference(SERVICE_TYPE, null,serviceURL, serviceSpec, serviceId, layerId, dataVersion); } @XmlValue public String getReference() { return buildRefrenceString(); } public void setReference(final String reference) { this.reference = reference; computeReferenceParts(); } /** * Split reference string. */ private void computeReferenceParts () { if (reference != null && reference.startsWith("${") && reference.endsWith("}")) { final String datas = reference.substring(2,reference.length()-1); final String[] dataSplit = datas.split("\\"+SEPARATOR); final int groupCount = dataSplit.length; final String datatype = dataSplit[0]; //get data type if (!datatype.isEmpty() && (datatype.equals(PROVIDER_LAYER_TYPE) || datatype.equals(PROVIDER_STYLE_TYPE) ) && (groupCount == 3 || groupCount == 4)) { type = datatype; } else if (!datatype.isEmpty() && datatype.equals(SERVICE_TYPE) && (groupCount == 5 || groupCount == 6)) { type = datatype; } else { throw new IllegalArgumentException("Reference data should be type of providerLayerType or providerStyleType or serviceType."); } this.dataVersion = null; if (type.equals(PROVIDER_LAYER_TYPE) || type.equals(PROVIDER_STYLE_TYPE)) { this.serviceSpec = null; this.serviceId = null; this.providerId = dataSplit[1]; //providerID this.layerId = dataSplit[2]; //layerID if (groupCount == 4) { this.dataVersion = dataSplit[3]; //dataVersion } } else if (type.equals(SERVICE_TYPE)) { this.providerId = null; this.serviceURL = dataSplit[1]; //http://localhost:8080/cstl/WS/wms/serviceID this.serviceSpec = dataSplit[2]; //WMS this.serviceId = dataSplit[3]; //serviceID this.layerId = dataSplit[4]; //layerID if (groupCount == 6) { this.dataVersion = dataSplit[5]; //dataVersion } } } else { throw new IllegalArgumentException("Reference should match pattern ${providerLayerType|providerId|layerId} or ${providerStyleType|providerId|layerId} or ${serviceType|serviceURL|serviceSpec|serviceId|layerId}."); } } /** * Make the reference string from parts. */ private String buildRefrenceString() { final StringBuffer buffer = new StringBuffer("${"); buffer.append(getDataType()).append(SEPARATOR); if (type.equals(PROVIDER_LAYER_TYPE) || type.equals(PROVIDER_STYLE_TYPE)) { buffer.append(providerId).append(SEPARATOR); } else if (type.equals(SERVICE_TYPE)) { buffer.append(serviceURL).append(SEPARATOR); buffer.append(serviceSpec).append(SEPARATOR); buffer.append(serviceId).append(SEPARATOR); } buffer.append(layerId); if (dataVersion != null) { buffer.append(SEPARATOR).append(dataVersion); } buffer.append("}"); return buffer.toString(); } /** * Return the type of dataRefrence, <code>providerLayerType</code> or <code>providerStyleType</code> or <code>serviceType</code>. * @return String or null if type is undefined. */ public String getDataType() { return type; } /** * The service specification part of the data. * @return String */ public String getServiceSpec(){ return serviceSpec; } /** * The service server URL part of the data. * @return String */ public String getServiceURL(){ return serviceURL; } /** * Read the service/provider id part of the data. * @return String */ public String getProviderOrServiceId(){ if (type.equals(PROVIDER_LAYER_TYPE) || type.equals(PROVIDER_STYLE_TYPE)) { return providerId; } else if (type.equals(SERVICE_TYPE)) { return serviceId; } return null; } /** * Read the service id part of the data. * @return String if DataReference is a Service type or null */ public String getServiceId(){ if (type.equals(SERVICE_TYPE)) { return serviceId; } return null; } /** * Read the provider id part of the data. * @return String provider id if DataReference is a Style or layer provider type or null */ public String getProviderId(){ if (type.equals(PROVIDER_LAYER_TYPE) || type.equals(PROVIDER_STYLE_TYPE)) { return providerId; } return null; } /** * Read the layer id part of the data. * @return Name */ public GenericName getLayerId(){ return NamesExt.valueOf(layerId); } /** * The dataVersion if not null. * @return Date or null if dataVersion not specified. */ public Date getDataVersion() { if (dataVersion != null) { Long time = Long.valueOf(dataVersion); return new Date(time); } return null; } @Override public int length() { return reference.length(); } @Override public char charAt(int index) { return reference.charAt(index); } @Override public CharSequence subSequence(int start, int end) { return reference.subSequence(start, end); } @Override public int hashCode() { int hash = 7; String reference = this.getReference(); hash = 37 * hash + (reference != null ? reference.hashCode() : 0); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final DataReference other = (DataReference) obj; String reference = this.getReference(); String otherReference = other.getReference(); if ((reference == null) ? (otherReference != null) : !reference.equals(otherReference)) { return false; } return true; } @Override public String toString() { return getReference(); } @Override public int compareTo(DataReference o) { if(o==null) return -1; return getReference().compareTo(o.getReference()); } }