/* (c) 2015 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.csw.store.internal; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.geoserver.catalog.CatalogInfo; import org.geoserver.csw.DownloadLinkHandler; import org.geoserver.csw.records.CSWRecordDescriptor; import org.geotools.data.CloseableIterator; import org.geotools.feature.AttributeImpl; import org.geotools.feature.ComplexAttributeImpl; import org.opengis.feature.Feature; import org.opengis.feature.Property; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.ComplexType; /** * {@link FeatureCustomizer} subclass to deal with CSW DublinCore records */ public class RecordCustomizer extends FeatureCustomizer { private final static AttributeDescriptor REFERENCES_DESCRIPTOR; private final static AttributeDescriptor VALUE_DESCRIPTOR; private final static String REFERENCES = "references"; private final static String TYPENAME = "RecordType"; static { REFERENCES_DESCRIPTOR = CSWRecordDescriptor.getDescriptor(REFERENCES); ComplexType referenceType = (ComplexType) REFERENCES_DESCRIPTOR.getType(); VALUE_DESCRIPTOR = (AttributeDescriptor) referenceType.getDescriptor("value"); } /** An instance of {@link DownloadLinkHandler}, used to deal with download links */ private DownloadLinkHandler downloadLinkHandler; public void setDownloadLinkHandler(DownloadLinkHandler downloadLinkHandler) { this.downloadLinkHandler = downloadLinkHandler; } public RecordCustomizer() { super(TYPENAME); } @Override public void customizeFeature(Feature feature, CatalogInfo resource) { CloseableIterator<String> links = null; List<Property> newReferencesList = new ArrayList<Property>(); String link = null; try { links = downloadLinkHandler.generateDownloadLinks(resource); if (links == null) { // No need to update the feature return; } while (links.hasNext()) { link = links.next(); newReferencesList.add(createReferencesElement(link)); } } finally { if (links != null) { try { links.close(); } catch (IOException e) { // ignore it } } } List<Property> propertyList = new ArrayList<Property>(); List<Property> oldValues = (List<Property>) feature.getValue(); Iterator<Property> oldValuesIterator = oldValues.iterator(); boolean insertReferences = false; // Copy all previous elements, references included while (oldValuesIterator.hasNext()) { Property prop = oldValuesIterator.next(); if (REFERENCES.equalsIgnoreCase(prop.getName().getLocalPart())) { insertReferences = true; } else if (insertReferences) { // link String should contain the last link generated // let's recycle it to generate the full download link newReferencesList.add(createReferencesElement(downloadLinkHandler.extractFullDownloadLink(link))); // append new references to the current collection // before going to other elements propertyList.addAll(newReferencesList); insertReferences = false; } propertyList.add(prop); } feature.setValue(propertyList); } /** * Create a new references element for the link */ private Property createReferencesElement(String link) { Property urlAttribute = new AttributeImpl(link, VALUE_DESCRIPTOR, null); // Setting references return new ComplexAttributeImpl(Collections.singletonList(urlAttribute), REFERENCES_DESCRIPTOR, null); } }