Package com.esri.gpt.framework.dcat

Source Code of com.esri.gpt.framework.dcat.DcatParser$Listener

/*
* Copyright 2013 Esri.
*
* 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 com.esri.gpt.framework.dcat;

import com.esri.gpt.framework.dcat.adaptors.DcatRecordAdaptor;
import com.esri.gpt.framework.dcat.dcat.DcatRecord;
import com.esri.gpt.framework.dcat.dcat.DcatRecordList;
import com.esri.gpt.framework.dcat.json.JsonArray;
import com.esri.gpt.framework.dcat.json.JsonAttribute;
import com.esri.gpt.framework.dcat.json.JsonAttributes;
import com.esri.gpt.framework.dcat.json.JsonRecord;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import java.io.IOException;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* DCAT parser.
*/
public class DcatParser {

  private static final Logger LOGGER = Logger.getLogger(DcatParser.class.getCanonicalName());

  private JsonReader jsonReader;

  /**
   * Creates instance of the parser.
   *
   * @param input input stream to parse
   */
  public DcatParser(InputStream input) throws UnsupportedEncodingException {
    this.jsonReader = new JsonReader(new InputStreamReader(input, "UTF-8"));
  }

  /**
   * Creates instance of the parser.
   *
   * @param reader data reader
   */
  public DcatParser(Reader reader) {
    this.jsonReader = new JsonReader(reader);
  }

  /**
   * Closes parser.
   */
  public void close() throws IOException {
    jsonReader.close();
  }

  /**
   * Parses data (event driven style).
   *
   * @param listener event listener
   * @throws DcatParseException if parsing fails
   */
  public void parse(final Listener listener) throws DcatParseException, IOException {
    ListenerInternal localListener = new ListenerInternal() {
      @Override
      public boolean onRecord(DcatRecord record) {
        LOGGER.log(Level.FINEST, record != null ? record.toString() : "<empty record>");
        listener.onRecord(record);
        return true;
      }
    };
    parse(localListener);
  }

  /**
   * Parses data (DOM building style).
   *
   * @param policy limit policy
   * @return list of records.
   * @throws DcatParseException if parsing fails
   */
  public DcatRecordList parse(final LimitPolicy policy) throws DcatParseException, IOException {
    final DcatRecordListImpl list = new DcatRecordListImpl();
    DcatParser.ListenerInternal listener = new DcatParser.ListenerInternal() {
      private void parse(final ListenerInternal listener) throws DcatParseException, IOException {
          if (!jsonReader.hasNext()) {
            throw new DcatParseException("No more data available.");
          }
          JsonToken token = jsonReader.peek();
          if (token != JsonToken.BEGIN_ARRAY) {
            throw new DcatParseException("No array found.");
          }

          parseRecords(listener);
      }

      @Override
      public boolean onRecord(DcatRecord record) {
        list.add(record);
        if (policy == null || list.size() >= policy.getLimit()) {
          return true;
        } else {
          policy.onLimit(list);
          return false;
        }
      }
    };
    parse(listener);
    return list;
  }

  /**
   * Parses DCAT using internal listener.
   *
   * @param listener internal listener
   * @throws DcatParseException if parsing DCAT fails
   */
  void parse(final ListenerInternal listener) throws DcatParseException, IOException {
      if (!jsonReader.hasNext()) {
        throw new DcatParseException("No more data available.");
      }

      JsonToken token = jsonReader.peek();
      if (token != JsonToken.BEGIN_ARRAY) {
        throw new DcatParseException("No array found.");
      }
      jsonReader.beginArray();

      parseRecords(listener);
  }

  /**
   * Parses DCAT records using internal listener.
   *
   * @param listener internal listener
   * @throws DcatParseException if parsing DCAT fails
   */
  void parseRecords(ListenerInternal listener) throws DcatParseException, IOException {

      while (jsonReader.hasNext()) {
        JsonToken token = jsonReader.peek();
        switch (token) {
          case BEGIN_OBJECT:
            jsonReader.beginObject();
            if (!parseRecord(listener)) {
              return;
            }
            break;
          default:
            throw new DcatParseException("Unexpected token in the data: " + token);
        }
      }

      jsonReader.endArray();
  }

  private boolean parseRecord(ListenerInternal listener) throws DcatParseException, IOException {
    JsonRecord record = new JsonRecord();
    while (jsonReader.hasNext()) {
      JsonToken token = jsonReader.peek();
      switch (token) {
        case NAME:
          parseAttribute(record);
          break;
        default:
          throw new DcatParseException("Unexpected token in the data: " + token);
      }
    }

    jsonReader.endObject();
    return listener.onRecord(new DcatRecordAdaptor(record));
  }

  private void parseAttribute(JsonRecord record) throws DcatParseException, IOException {
    String attrName = jsonReader.nextName();
    while (jsonReader.hasNext()) {
      JsonToken token = jsonReader.peek();
      switch (token) {
        case STRING:
          record.put(attrName, new JsonAttribute(jsonReader.nextString()));
          return;
        case NUMBER:
          record.put(attrName, new JsonAttribute(jsonReader.nextDouble()));
          return;
        case BOOLEAN:
          record.put(attrName, new JsonAttribute(jsonReader.nextBoolean()));
          return;
        case BEGIN_ARRAY:
          if ("distribution".equals(attrName)) {
            jsonReader.beginArray();
            parseDistributions(record.getDistribution());
            jsonReader.endArray();
          } else if ("keyword".equals(attrName)) {
            jsonReader.beginArray();
            parseKeywords(record.getKeywords());
            jsonReader.endArray();
          } else {
            // skip
            jsonReader.skipValue();
          }
          return;
        default:
          throw new DcatParseException("Unexpected token in the data: " + token);
      }
    }
  }
 
  private void parseKeywords(List<JsonAttribute> keywords) throws DcatParseException, IOException {

    while (jsonReader.hasNext()) {
      JsonToken token = jsonReader.peek();
      switch (token) {
        case END_ARRAY:
          jsonReader.endArray();
          break;
        case STRING:
          keywords.add(new JsonAttribute(jsonReader.nextString()));
          break;
        case NUMBER:
          keywords.add(new JsonAttribute(jsonReader.nextDouble()));
          break;
        case BOOLEAN:
          keywords.add(new JsonAttribute(jsonReader.nextBoolean()));
          break;
        default:
          throw new DcatParseException("Unexpected token in the data: " + token);
      }
    }
  }

  private void parseDistributions(JsonArray<JsonAttributes> distributions) throws DcatParseException, IOException {

    while (jsonReader.hasNext()) {
      JsonToken token = jsonReader.peek();
      switch (token) {
        case BEGIN_OBJECT:
          jsonReader.beginObject();
          parseDistribution(distributions);
          jsonReader.endObject();
          break;
        default:
          throw new DcatParseException("Unexpected token in the data: " + token);
      }
    }

  }

  private void parseDistribution(JsonArray<JsonAttributes> distributions) throws DcatParseException, IOException {
    JsonAttributes attributes = new JsonAttributes();
    while (jsonReader.hasNext()) {
      JsonToken token = jsonReader.peek();
      switch (token) {
        case NAME:
          parseAttribute(attributes);
          break;
        default:
          throw new DcatParseException("Unexpected token in the data: " + token);
      }
    }

    distributions.add(attributes);
  }

  private void parseAttribute(JsonAttributes attributes) throws DcatParseException, IOException {
    String attrName = jsonReader.nextName();
    while (jsonReader.hasNext()) {
      JsonToken token = jsonReader.peek();
      switch (token) {
        case STRING:
          attributes.put(attrName, new JsonAttribute(jsonReader.nextString()));
          return;
        case NUMBER:
          attributes.put(attrName, new JsonAttribute(jsonReader.nextDouble()));
          return;
        case BOOLEAN:
          attributes.put(attrName, new JsonAttribute(jsonReader.nextBoolean()));
          return;
        default:
          throw new DcatParseException("Unexpected token in the data: " + token);
      }
    }
  }

  /**
   * Record listener.
   */
  public static interface Listener {

    /**
     * Called upon a single record parsed.
     *
     * @param record record
     */
    void onRecord(DcatRecord record);
  }

  /**
   * Limit policy.
   */
  public static interface LimitPolicy {

    /**
     * Gets size limit.
     *
     * @return size limit
     */
    long getLimit();

    /**
     * Called when size reached limit.
     *
     * @param recordsList current list of records
     */
    void onLimit(DcatRecordList recordsList);
  }

  static interface ListenerInternal {

    boolean onRecord(DcatRecord record);
  }

  private static class DcatRecordListImpl extends ArrayList<DcatRecord> implements DcatRecordList {
  }
}
TOP

Related Classes of com.esri.gpt.framework.dcat.DcatParser$Listener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.