Package com.google.apphosting.utils.config

Source Code of com.google.apphosting.utils.config.IndexYamlReader$IndexYaml$Property

// Copyright 2010 Google Inc. All Rights Reserved.

package com.google.apphosting.utils.config;

import net.sourceforge.yamlbeans.YamlException;
import net.sourceforge.yamlbeans.YamlReader;

import java.io.Reader;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;

/**
* Class to parse index.yaml into a IndexesXml object.
*
*/
public class IndexYamlReader {

  public static final String INDEX_DEFINITIONS_TAG =
      "!!python/object:google.appengine.datastore.datastore_index.IndexDefinitions";
  public static final String INDEX_TAG =
      "!!python/object:google.appengine.datastore.datastore_index.Index";
  public static final String PROPERTY_TAG =
      "!!python/object:google.appengine.datastore.datastore_index.Property";

  /**
   * Wrapper around IndexesXml to make the JavaBeans properties match the YAML
   * file syntax.
   */
  public static class IndexYaml {

    public String application;
    /**
     * JavaBean wrapper for Index entries in IndexesXml.
     * This class must be kept in sync with apphosting/datastore/datastore_index.py
     */
    public static class Index {
      public String kind;
      protected boolean ancestor;
      public List<Property> properties;

      public void setAncestor(String ancestor) {
        this.ancestor = YamlUtils.parseBoolean(ancestor);
      }

      public String getAncestor() {
        return "" + ancestor;
      }
    }

    /**
     * JavaBean wrapper for IndexesXml properties.
     */
    public static class Property {
      private String name = null;
      private String direction = null;
      private String mode = null;

      public void setDirection(String direction) {
        if ("desc".equals(direction) || "asc".equals(direction)) {
          this.direction = direction;
        } else {
          throw new AppEngineConfigException(
              "Invalid direction '" + direction + "': expected 'asc' or 'desc'.");
        }
      }

      public String getName() {
        return name;
      }

      public void setName(String name) {
        this.name = name;
      }

      public String getDirection() {
        return direction;
      }

      public void setMode(String mode) {
        if (mode != null && mode.equals("null")) {
          mode = null;
        }

        if (mode != null && !(mode.equals("geospatial") || mode.equals("segment"))) {
          throw new AppEngineConfigException("Invalid mode: '" + mode);
        }

        this.mode = mode;
      }

      public String getMode() {
        return mode;
      }
    }

    private List<Index> indexes;

    public List<Index> getIndexes() {
      return indexes;
    }

    public void setIndexes(List<Index> indexes) {
      this.indexes = indexes;
    }

    public IndexesXml toXml(IndexesXml xml) {
      if (indexes == null) {
        throw new AppEngineConfigException("Empty index configuration.");
      }
      if (xml == null) {
        xml = new IndexesXml();
      }
      for (Index yamlIndex : indexes) {
        if (yamlIndex.kind == null) {
          throw new AppEngineConfigException("Index missing required element 'kind'");
        }
        IndexesXml.Index xmlIndex = xml.addNewIndex(yamlIndex.kind, yamlIndex.ancestor);
        if (yamlIndex.properties != null) {
          for (Property property : yamlIndex.properties) {
            if (property.getName() == null) {
              throw new AppEngineConfigException("Property is missing required element 'name'.");
            }
            xmlIndex.addNewProperty(
                property.getName(), property.getDirection(), property.getMode());
          }
        }
      }
      return xml;
    }
  }

  public static IndexesXml parse(Reader yaml, IndexesXml xml) {
    List<IndexesXml> list;
    try {
      list = parseMultiple(yaml, xml);
    } catch (YamlException ex) {
      throw new AppEngineConfigException(ex.getMessage(), ex);
    }
    if (0 == list.size()) {
      throw new AppEngineConfigException("Empty index configuration.");
    }
    if (list.size() > 1) {
      throw new AppEngineConfigException(
          "yaml unexepectedly contains more than one document: " + list.size());
    }
    return list.get(0);
  }

  /**
   * Parses the Yaml from {@code yaml} into a Yaml document and deserializes
   * the document into an instance of {@link IndexesXml}.
   * @param yaml  A {@link String} from which to read the Yaml. This String is allowed to
   * be in the style generated by the admin server, including the Python-specific tags.
   * This method will safely ignore those tags.
   * @return An instance of {@link IndexesXml}.
   */
  public static IndexesXml parse(String yaml) {
    return parse(new StringReader(clean(yaml)), null);
  }

  /**
   * Parses the Yaml from {@code yaml} into one or more documents, and
   * deserializes the documents into one or more instances of {@link IndexesXml}
   * which are returned in a {@link List}.
   *
   * @param yaml A {@link String} from which to read the Yyaml. This String is
   *        allowed to be in the style generated by the admin server, including
   *        the Python-specific tags. This method will safely ignore those tags.
   * @return A {@link List} of {@link IndexesXml} instances representing one or
   *         more parsed Yaml documents.
   */
  public static List<IndexesXml> parseMultiple(String yaml) {
    try {
      return parseMultiple(new StringReader(clean(yaml)), null);
    } catch (YamlException ex) {
      throw new AppEngineConfigException(ex.getMessage(), ex);
    }
  }

  /**
   * Cleans a Yaml String by removing Pyton-specific tags.
   * These tags are written by the admin server when it generates
   * Yaml representing indexes.
   * @param yaml A {@link String} containing Yaml
   * @return The cleaned {@link String}
   */
  private static String clean(String yaml) {
    return yaml
        .replaceAll(INDEX_DEFINITIONS_TAG, "")
        .replaceAll(INDEX_TAG, "")
        .replaceAll(PROPERTY_TAG, "")
        .trim();
  }

  /**
   * Parses the Yaml from {@code yaml} into one or more documents, and
   * deserializes the documents into one or more instances of {@link IndexesXml}
   * which are returned in a {@link List}.
   *
   * @param yaml A {@link Reader} from which to read the yaml
   * @param xml A possibly {@code null} {@link IndexesXml} instance. If this
   *        parameter is not {@code null} then each of the yaml documents will
   *        be deserialized into it. This parameter is intended to be
   *        used in cases where there is only one Yaml document expected and so
   *        there will only be one instance of {@link IndexesXml} in the
   *        returned {@link List}. If this parameter is not {@code null} and the
   *        returned list has length greater than 1, then the list will contain
   *        multiple copies of this parameter.
   * @return A {@link List} of {@link IndexesXml} instances representing one or
   *         more parsed Yaml documents.
   * @throws YamlException If the Yaml parser has trobule parsing.
   */
  private static List<IndexesXml> parseMultiple(Reader yaml, IndexesXml xml) throws YamlException {
    YamlReader reader = new YamlReader(yaml);
    reader.getConfig().setPropertyElementType(IndexYaml.class, "indexes", IndexYaml.Index.class);
    reader.getConfig().setPropertyElementType(
        IndexYaml.Index.class, "properties", IndexYaml.Property.class);
    List<IndexesXml> list = new LinkedList<IndexesXml>();
    while (true) {
      IndexYaml indexYaml = reader.read(IndexYaml.class);
      if (null == indexYaml) {
        break;
      } else {
        list.add(indexYaml.toXml(xml));
      }
    }
    return list;
  }

}
TOP

Related Classes of com.google.apphosting.utils.config.IndexYamlReader$IndexYaml$Property

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.