Changeset 6917


Ignore:
Timestamp:
01/18/16 16:40:03 (8 years ago)
Author:
Oliver Schonefeld
Message:
  • enhance endpoint description parser
Location:
SRUClient/trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • SRUClient/trunk/src/main/java/eu/clarin/sru/client/fcs/ClarinFCSEndpointDescription.java

    r5804 r6917  
    2121    private final List<URI> capabilites;
    2222    private final List<DataView> supportedDataViews;
     23    private final List<Layer> supportedLayers;
    2324    private final List<ResourceInfo> resources;
    2425
    2526
    2627    ClarinFCSEndpointDescription(int version, List<URI> capabilites,
    27             List<DataView> supportedDataViews, List<ResourceInfo> resources) {
     28            List<DataView> supportedDataViews, List<Layer> supportedLayers,
     29            List<ResourceInfo> resources) {
    2830        this.version = version;
    2931        if ((capabilites != null) && !capabilites.isEmpty()) {
     
    3840            this.supportedDataViews = Collections.emptyList();
    3941        }
     42        if ((supportedLayers != null) && !supportedLayers.isEmpty()) {
     43            this.supportedLayers =
     44                    Collections.unmodifiableList(supportedLayers);
     45        } else {
     46            this.supportedLayers = Collections.emptyList();
     47        }
    4048        if ((resources != null) && !resources.isEmpty()) {
    4149            this.resources = Collections.unmodifiableList(resources);
     
    8593
    8694    /**
     95     * Get the list of data views supported by this endpoint.
     96     *
     97     * @return the list of data views supported by this endpoint
     98     */
     99    public List<Layer> getSupportedLayers() {
     100        return supportedLayers;
     101    }
     102
     103
     104    /**
    87105     * Get the list of top-level resources of this endpoint.
    88106     *
     
    98116     */
    99117    public static final class DataView implements Serializable {
    100         private static final long serialVersionUID = -5628565233032672627L;
    101 
    102 
    103118        /**
    104119         * Enumeration to indicate the delivery policy of a data view.
     
    114129            NEED_TO_REQUEST;
    115130        } // enum PayloadDelivery
     131        private static final long serialVersionUID = -5628565233032672627L;
    116132        private final String identifier;
    117133        private final String mimeType;
     
    188204            return sb.toString();
    189205        }
    190 
    191206    } // class DataView
     207
     208
     209    public static final class Layer implements Serializable {
     210        /**
     211         * Enumeration to indicate the content encoding of a layer.
     212         */
     213        public enum ContentEncoding {
     214            /**
     215             * The layer is encoded as content values.
     216             */
     217            VALUE,
     218            /**
     219             * The layer is encoded just as segment units.
     220             */
     221            EMPTY
     222        }
     223        private static final long serialVersionUID = 6641490182609459912L;
     224        private final String identifier;
     225        private final URI resultId;
     226        private final String layerType;
     227        private final ContentEncoding encoding;
     228        private final String qualifier;
     229        private final String altValueInfo;
     230        private final URI altValueInfoURI;
     231
     232
     233        public Layer(String identifier, URI resultId, String layerType,
     234                ContentEncoding encoding, String qualifier,
     235                String altValueInfo, URI altValueInfoURI) {
     236            if (identifier == null) {
     237                throw new NullPointerException("identifier == null");
     238            }
     239            if (identifier.isEmpty()) {
     240                throw new IllegalArgumentException("identifier is empty");
     241            }
     242            this.identifier = identifier;
     243
     244            if (resultId == null) {
     245                throw new NullPointerException("resultId == null");
     246            }
     247            this.resultId = resultId;
     248
     249            if (layerType == null) {
     250                throw new NullPointerException("layerType == null");
     251            }
     252            if (layerType.isEmpty()) {
     253                throw new IllegalArgumentException("layerType is empty");
     254            }
     255            this.layerType = layerType;
     256            this.encoding = (encoding != null)
     257                    ? encoding
     258                    : ContentEncoding.VALUE;
     259            this.qualifier = qualifier;
     260            this.altValueInfo = altValueInfo;
     261            this.altValueInfoURI = altValueInfoURI;
     262        }
     263
     264
     265        /**
     266         * Get the identifier of this layer
     267         *
     268         * @return the identifier of the layer
     269         */
     270        public String getIdentifier() {
     271            return identifier;
     272        }
     273
     274
     275        /**
     276         * Get the result URI of this layer
     277         *
     278         * @return the result URI of the layer
     279         */
     280        public URI getResultId() {
     281            return resultId;
     282        }
     283
     284
     285        /**
     286         * Get the layer type of this layer
     287         *
     288         * @return the layer type of the layer
     289         */
     290        public String getLayerType() {
     291            return layerType;
     292        }
     293
     294
     295        /**
     296         * Get the content encoding of this layer
     297         *
     298         * @return the content encoding of the layer
     299         */
     300        public ContentEncoding getEncoding() {
     301            return encoding;
     302        }
     303
     304
     305        /**
     306         * Get the qualifier of this layer
     307         *
     308         * @return the qualifier of the layer or <code>null</code> if none
     309         */
     310        public String getQualifier() {
     311            return qualifier;
     312        }
     313
     314
     315        /**
     316         * Get the alternative value information of this layer
     317         *
     318         * @return the alternative value information of the layer or
     319         *         <code>null</code> if none
     320         */
     321        public String getAltValueInfo() {
     322            return altValueInfo;
     323        }
     324
     325
     326        /**
     327         * Get the alternative value information URI of this layer
     328         *
     329         * @return the alternative value information URI of the layer or
     330         *         <code>null</code> if none
     331         */
     332        public URI getAltValueInfoURI() {
     333            return altValueInfoURI;
     334        }
     335
     336
     337        @Override
     338        public String toString() {
     339            StringBuilder sb = new StringBuilder();
     340            sb.append(getClass().getSimpleName());
     341            sb.append("[");
     342            sb.append("identifier=").append(identifier);
     343            sb.append(", result-id=").append(resultId);
     344            sb.append(", layer-type=").append(layerType);
     345            if (encoding != null) {
     346                sb.append(", encoding=").append(encoding);
     347            }
     348            if (qualifier != null) {
     349                sb.append(", qualifier=").append(qualifier);
     350            }
     351            if (altValueInfo != null) {
     352                sb.append(", alt-value-info=").append(altValueInfo);
     353            }
     354            if (altValueInfoURI != null) {
     355                sb.append(", alt-value-info-uri=").append(altValueInfoURI);
     356            }
     357            sb.append("]");
     358            return sb.toString();
     359        }
     360    }
    192361
    193362
     
    204373        private final List<String> languages;
    205374        private final List<DataView> availableDataViews;
     375        private final List<Layer> availableLayers;
    206376        private final List<ResourceInfo> subResources;
    207377
     
    213383                Map<String, String> description, String landingPageURI,
    214384                List<String> languages, List<DataView> availableDataViews,
     385                List<Layer> availableLayers,
    215386                List<ResourceInfo> subResources) {
    216387            if (pid == null) {
     
    247418                    Collections.unmodifiableList(availableDataViews);
    248419
     420            if ((availableLayers != null) && !availableLayers.isEmpty()) {
     421                this.availableLayers =
     422                        Collections.unmodifiableList(availableLayers);
     423            } else {
     424                this.availableLayers = Collections.emptyList();
     425            }
     426
    249427            if ((subResources != null) && !subResources.isEmpty()) {
    250428                this.subResources = Collections.unmodifiableList(subResources);
     
    378556
    379557
     558        /**
     559         * Get the list of data views that are available for this resource.
     560         *
     561         * @return the list of data views available for this resource
     562         */
    380563        public List<DataView> getAvailableDataViews() {
    381564            return availableDataViews;
    382565        }
    383566
     567
     568        /**
     569         * (ADV-FCS) Get the list of layers that are available for this
     570         * resource.
     571         *
     572         * @return the list of layers views available for this resource
     573         */
     574        public List<Layer> getAvailableLayers() {
     575            return availableLayers;
     576        }
    384577    } // class ResourceInfo
    385578
  • SRUClient/trunk/src/main/java/eu/clarin/sru/client/fcs/ClarinFCSEndpointDescriptionParser.java

    r6903 r6917  
    3838import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescription.DataView;
    3939import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescription.DataView.DeliveryPolicy;
     40import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescription.Layer;
     41import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescription.Layer.ContentEncoding;
    4042import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescription.ResourceInfo;
    4143
     
    6062    private static final QName ED_ROOT_ELEMENT =
    6163            new QName(ED_NS_URI, "EndpointDescription");
    62     private static final int EXPECTED_VERSION = 1;
     64    private static final int VERSION_1 = 1;
     65    private static final int VERSION_2 = 2;
    6366    private static final String CAPABILITY_PREFIX =
    6467            "http://clarin.eu/fcs/capability/";
    6568    private static final URI CAPABILITY_BASIC_SEARCH =
    6669            URI.create("http://clarin.eu/fcs/capability/basic-search");
     70    private static final URI CAPABILITY_ADVANCED_SEARCH =
     71            URI.create("http://clarin.eu/fcs/capability/advanced-search");
    6772    private static final String MIMETYPE_HITS_DATAVIEW =
    6873            "application/x-clarin-fcs-hits+xml";
     
    105110            throws XMLStreamException, SRUClientException {
    106111        final int version = parseVersion(reader);
    107         // FIXME: actually handle other version
    108         if ((version != EXPECTED_VERSION) && (version != 2)) {
     112        if ((version != VERSION_1) && (version != VERSION_2)) {
    109113            throw new SRUClientException("Attribute 'version' of " +
    110                     "element '<EndpointDescription>' must be of value '1'");
    111         }
    112         logger.error("VERSION: {}", version);
     114                    "element '<EndpointDescription>' must be of value '1' or '2'");
     115        }
    113116        reader.next(); // consume start tag
    114117
     
    139142        } // while
    140143        XmlStreamReaderUtils.readEnd(reader, ED_NS_URI, "Capabilities");
    141         if ((capabilities == null) ||
    142                 (capabilities.indexOf(CAPABILITY_BASIC_SEARCH) == -1)) {
     144
     145        if (capabilities == null) {
     146            throw new SRUClientException("Endpoint must support at " +
     147                    "least one capability!");
     148        }
     149        final boolean hasBasicSearch =
     150                (capabilities.indexOf(CAPABILITY_BASIC_SEARCH) != -1);
     151        final boolean hasAdvancedSearch =
     152                (capabilities.indexOf(CAPABILITY_ADVANCED_SEARCH) != -1);
     153        if (!hasBasicSearch) {
    143154            throw new SRUClientException("Endpoint must support " +
    144155                    "'basic-search' (" + CAPABILITY_BASIC_SEARCH +
     
    205216
    206217        // SupportedLayers
    207         // FIXME: actually do something useful
     218        List<Layer> supportedLayers = null;
    208219        if (XmlStreamReaderUtils.readStart(reader, ED_NS_URI,
    209220                "SupportedLayers", false)) {
     221            while (XmlStreamReaderUtils.readStart(reader, ED_NS_URI,
     222                    "SupportedLayer", (supportedLayers == null), true)) {
     223                final String id = XmlStreamReaderUtils.readAttributeValue(reader, null, "id");
     224                if ((id.indexOf(' ') != -1) || (id.indexOf(',') != -1) ||
     225                        (id.indexOf(';') != -1)) {
     226                    throw new XMLStreamException("Value of attribute 'id' on " +
     227                            "element '<SupportedLayer>' may not contain the " +
     228                            "characters ',' (comma) or ';' (semicolon) " +
     229                            "or ' ' (space)", reader.getLocation());
     230                }
     231                URI resultId = null;
     232                final String s1 =
     233                        XmlStreamReaderUtils.readAttributeValue(reader,
     234                                null, "result-id");
     235                try {
     236                    resultId = new URI(s1);
     237                } catch (URISyntaxException e) {
     238                    throw new XMLStreamException("'result-id' must be encoded " +
     239                            "as URIs (offending value = '" + s1 + "')",
     240                            reader.getLocation(), e);
     241                }
     242                final ContentEncoding encoding = parseContentEncoding(reader);
     243                String qualifier = XmlStreamReaderUtils.readAttributeValue(reader, null, "qualifier", false);
     244                String altValueInfo = XmlStreamReaderUtils.readAttributeValue(reader, null, "alt-value-info", false);
     245                URI altValueInfoURI = null;
     246                final String s2 =
     247                        XmlStreamReaderUtils.readAttributeValue(reader, null,
     248                                "alt-value-info-uri", false);
     249                if (s2 != null) {
     250                    try {
     251                        altValueInfoURI = new URI(s2);
     252                    } catch (URISyntaxException e) {
     253                        throw new XMLStreamException("'alt-value-info-uri' must be encoded " +
     254                                "as URIs (offending value = '" + s2 + "')",
     255                                reader.getLocation(), e);
     256                    }
     257                }
     258                reader.next(); // consume element
     259                final String layer = XmlStreamReaderUtils.readString(reader, true);
     260                logger.debug("layer: id={}, resultId={}, layer={}, encoding={}, qualifier={}, alt-value-info={}, alt-value-info-uri={}",
     261                        id, resultId, layer, encoding, qualifier, altValueInfo, altValueInfoURI);
     262
     263                XmlStreamReaderUtils.readEnd(reader, ED_NS_URI, "SupportedLayer");
     264                if (supportedLayers == null) {
     265                    supportedLayers = new ArrayList<Layer>();
     266                }
     267                supportedLayers.add(new Layer(id, resultId, layer,
     268                        encoding, qualifier, altValueInfo,
     269                        altValueInfoURI));
     270            } // while
    210271            XmlStreamReaderUtils.readEnd(reader, ED_NS_URI,
    211272                    "SupportedLayers", true);
    212273        }
     274        if (hasAdvancedSearch && (supportedLayers == null)) {
     275            throw new SRUClientException("Endpoint must declare " +
     276                    "all supported layers (<SupportedLayers>) if they " +
     277                    "provide the 'advanced-search' (" +
     278                    CAPABILITY_ADVANCED_SEARCH + ") capability");
     279        }
     280        if (!hasAdvancedSearch && (supportedLayers != null)) {
     281            // XXX: hard error?!
     282            logger.warn("Endpoint superflously declared supported " +
     283                    "layers (<SupportedLayers> without providing the " +
     284                    "'advanced-search' (" + CAPABILITY_ADVANCED_SEARCH + ") capability");
     285        }
    213286
    214287        // Resources
    215288        final List<ResourceInfo> resources =
    216                 parseResources(reader, 0, maxDepth, supportedDataViews);
     289                parseResources(reader, 0, maxDepth,
     290                        supportedDataViews, supportedLayers);
    217291
    218292        // skip over extensions
     
    231305
    232306        return new ClarinFCSEndpointDescription(version, capabilities,
    233                 supportedDataViews, resources);
     307                supportedDataViews, supportedLayers, resources);
    234308    }
    235309
     
    248322
    249323    private static List<ResourceInfo> parseResources(XMLStreamReader reader,
    250             int depth, int maxDepth, List<DataView> supportedDataviews)
    251             throws XMLStreamException {
     324            int depth, int maxDepth, List<DataView> supportedDataviews,
     325            List<Layer> supportedLayers) throws XMLStreamException {
    252326        List<ResourceInfo> resources = null;
    253327
     
    298372            logger.debug("languages: {}", languages);
    299373
     374            // AvailableDataViews
    300375            XmlStreamReaderUtils.readStart(reader, ED_NS_URI, "AvailableDataViews", true, true);
    301376            final String dvs = XmlStreamReaderUtils.readAttributeValue(reader, null, "ref", true);
    302377            reader.next(); // consume start tag
    303378            XmlStreamReaderUtils.readEnd(reader, ED_NS_URI, "AvailableDataViews");
    304 
    305379            List<DataView> dataviews = null;
    306380            for (String dv : dvs.split("\\s+")) {
     
    324398            logger.debug("DataViews: {}", dataviews);
    325399
    326 
    327             // FIXME: actually do something useful
    328             if (XmlStreamReaderUtils.readStart(reader, ED_NS_URI, "AvailableLayers", false, true)) {
    329                 final String ls = XmlStreamReaderUtils.readAttributeValue(reader, null, "ref", true);
     400            // AvailableLayers
     401            List<Layer> layers = null;
     402            if (XmlStreamReaderUtils.readStart(reader, ED_NS_URI,
     403                    "AvailableLayers", false, true)) {
     404                final String ls =
     405                        XmlStreamReaderUtils.readAttributeValue(reader,
     406                                null, "ref", true);
    330407                reader.next(); // consume start tag
    331408                XmlStreamReaderUtils.readEnd(reader, ED_NS_URI, "AvailableLayers");
    332                 logger.debug("Layers: {}", dataviews);
     409                for (String l : ls.split("\\s+")) {
     410                    boolean found = false;
     411                    for (Layer layer : supportedLayers) {
     412                        if (layer.getIdentifier().equals(l)) {
     413                            found = true;
     414                            if (layers == null) {
     415                                layers = new ArrayList<Layer>();
     416                            }
     417                            layers.add(layer);
     418                            break;
     419                        }
     420                    } // for
     421                    if (!found) {
     422                        throw new XMLStreamException("Layer with id '" + l +
     423                                "' was not declared in <SupportedLayers>",
     424                                reader.getLocation());
     425                    }
     426                } // for
     427                logger.debug("Layers: {}", layers);
    333428            }
    334429
     
    341436                        (nextDepth < maxDepth)) {
    342437                    subResources = parseResources(reader, nextDepth,
    343                             maxDepth, supportedDataviews);
     438                            maxDepth, supportedDataviews, supportedLayers);
    344439                } else {
    345440                    XmlStreamReaderUtils.skipTag(reader, ED_NS_URI,
     
    366461            }
    367462            resources.add(new ResourceInfo(pid, title, description,
    368                     landingPageURI, languages, dataviews, subResources));
     463                    landingPageURI, languages, dataviews, layers,
     464                    subResources));
    369465        } // while
    370466        XmlStreamReaderUtils.readEnd(reader, ED_NS_URI, "Resources");
     
    427523    }
    428524
     525
     526    private static ContentEncoding parseContentEncoding(XMLStreamReader reader)
     527            throws XMLStreamException {
     528        final String s = XmlStreamReaderUtils.readAttributeValue(reader,
     529                null, "encoding", false);
     530        if (s != null) {
     531            if ("value".equals(s)) {
     532                return ContentEncoding.VALUE;
     533            } else if ("need-to-request".equals(s)) {
     534                return ContentEncoding.EMPTY;
     535            } else {
     536                throw new XMLStreamException("Unexpected value '" + s +
     537                                "' for attribute 'encoding' on " +
     538                                "element '<SupportedLayer>'",
     539                        reader.getLocation());
     540            }
     541        } else {
     542            return null;
     543        }
     544    }
     545
    429546} // class ClarinFCSEndpointDescriptionParser
  • SRUClient/trunk/src/test/java/eu/clarin/sru/client/TestUtils.java

    r6912 r6917  
    239239                    dataView.getDeliveryPolicy());
    240240        } // for
     241        for (ClarinFCSEndpointDescription.Layer layer :
     242            ed.getSupportedLayers()) {
     243            logger.info("  supportedLayer: id={}, result-id={}, " +
     244                    "layer-type={}, encoding={}, qualifier={}, " +
     245                    "alt-value-info={}, alt-value-info-uri={}",
     246                    layer.getIdentifier(),
     247                    layer.getResultId(),
     248                    layer.getLayerType(),
     249                    layer.getEncoding(),
     250                    layer.getQualifier(),
     251                    layer.getAltValueInfo(),
     252                    layer.getAltValueInfoURI());
     253        }
    241254        dumpResourceInfo(ed.getResources(), 1, "  ");
    242255    }
     
    261274                logger.info("{}    available dataviews: type={}, policy={}",
    262275                        indent, dv.getMimeType(), dv.getDeliveryPolicy());
     276            }
     277            for (ClarinFCSEndpointDescription.Layer l :
     278                ri.getAvailableLayers()) {
     279                logger.info("{}    available layers: result-id={}, layer-type={}",
     280                        indent, l.getResultId(), l.getLayerType());
    263281            }
    264282            if (ri.hasSubResources()) {
Note: See TracChangeset for help on using the changeset viewer.