/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2012 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.csw.response; import java.util.List; import net.opengis.cat.csw20.RequestBaseType; import org.geoserver.csw.records.AbstractRecordDescriptor; import org.geoserver.csw.records.GenericRecordBuilder; import org.geoserver.csw.records.iso.MetaDataDescriptor; import org.geoserver.platform.ServiceException; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.referencing.CRS; import org.geotools.xml.transform.Translator; import org.opengis.feature.ComplexAttribute; import org.opengis.feature.Feature; import org.opengis.feature.Property; import org.opengis.feature.type.Name; import org.xml.sax.ContentHandler; import org.xml.sax.helpers.AttributesImpl; /** * Encodes a FeatureCollection containing {@link MetaDataDescriptor} features into the specified * XML according to the chosen profile, brief, summary or full * * * @author Niels Charlier */ public class MetaDataTransformer extends AbstractRecordTransformer { static final String CSW_ROOT_LOCATION = "http://schemas.opengis.net/csw/2.0.2/"; public MetaDataTransformer(RequestBaseType request, boolean canonicalSchemaLocation) { super(request, canonicalSchemaLocation, MetaDataDescriptor.NAMESPACES); } @Override public Translator createTranslator(ContentHandler handler) { return new MetaDataTranslator(handler); } @Override public boolean canHandleRespose(CSWRecordsResult response) { return true; } class MetaDataTranslator extends AbstractRecordTranslator { public MetaDataTranslator(ContentHandler handler) { super(handler); } public void encode(CSWRecordsResult response, Feature f) { encodeProperty(f, f); } private void encodeProperty(Feature f, Property p) { if (p instanceof ComplexAttribute) { String prefix = MetaDataDescriptor.NAMESPACES.getPrefix(p.getName().getNamespaceURI()); AttributesImpl atts = new AttributesImpl() ; for (Property p2 : ((ComplexAttribute)p).getProperties() ) { if (p2.getName().getLocalPart().substring(0, 1).equals("@")) { String name = p2.getName().getLocalPart().substring(1); atts.addAttribute("", name, name , "", p2.getValue().toString()); } } start(prefix + ":" + p.getName().getLocalPart(), atts); for (Property p2 : ((ComplexAttribute)p).getProperties() ) { if (!p2.getName().getLocalPart().substring(0, 1).equals("@")) { encodeProperty(f, p2); } } end(prefix + ":" + p.getName().getLocalPart()); } else if (MetaDataDescriptor.RECORD_BBOX_NAME.equals(p.getName())) { // grab the original bounding boxes from the user data (the geometry is an aggregate) List<ReferencedEnvelope> originalBoxes = (List<ReferencedEnvelope>) p .getUserData().get(GenericRecordBuilder.ORIGINAL_BBOXES); for (ReferencedEnvelope re : originalBoxes) { try { ReferencedEnvelope wgs84re = re.transform( CRS.decode(AbstractRecordDescriptor.DEFAULT_CRS_NAME), true); String minx = String.valueOf(wgs84re.getMinX()); String miny = String.valueOf(wgs84re.getMinY()); String maxx = String.valueOf(wgs84re.getMaxX()); String maxy = String.valueOf(wgs84re.getMaxY()); AttributesImpl attributes = new AttributesImpl(); addAttribute(attributes, "crs", AbstractRecordDescriptor.DEFAULT_CRS_NAME); start("gmd:EX_GeographicBoundingBox", attributes); element("gmd:westBoundLongitude", minx ); element("gmd:southBoundLatitude", miny); element("gmd:eastBoundLongitude", maxx); element("gmd:northBoundLatitude", maxy); end("gmd:EX_GeographicBoundingBox"); } catch (Exception e) { throw new ServiceException("Failed to encode the current record: " + f, e); } } } else { encodeSimpleLiteral(p); } } private void encodeSimpleLiteral(Property p) { String value = p.getValue().toString(); Name dn = p.getDescriptor().getName(); String name = dn.getLocalPart(); String prefix = MetaDataDescriptor.NAMESPACES.getPrefix(dn.getNamespaceURI()); AttributesImpl attributes = new AttributesImpl(); element(prefix + ":" + name, value, attributes); } } }