Package org.waveprotocol.wave.model.schema

Source Code of org.waveprotocol.wave.model.schema.AbstractXmlSchemaConstraints

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.waveprotocol.wave.model.schema;

import org.waveprotocol.wave.model.document.operation.automaton.DocumentSchema;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.Preconditions;
import org.waveprotocol.wave.model.util.StringMap;
import org.waveprotocol.wave.model.util.StringSet;

import java.util.Collections;
import java.util.List;

/**
* Helper base class for somewhat simplifying the chore of defining schema
* constraints, while allowing any method to be overridden for Turing complete
* schema validation goodness.
*
* @author danilatos@google.com (Daniel Danilatos)
*/
public abstract class AbstractXmlSchemaConstraints implements DocumentSchema {
  private static final String IMPLICIT_ROOT_TYPE = "";

  // Signals an error if type is IMPLICIT_ROOT_TYPE, and translates null to IMPLICIT_ROOT_TYPE.
  // We do this because we can't use null as a key in StringMaps.
  private static String fixType(String type) {
    Preconditions.checkArgument(!IMPLICIT_ROOT_TYPE.equals(type), "Invalid type");
    if (type == null) {
      return IMPLICIT_ROOT_TYPE;
    } else {
      return type;
    }
  }

  private static void checkNotTopLevel(String type) {
    Preconditions.checkArgument(!IMPLICIT_ROOT_TYPE.equals(type), "Invalid type");
    Preconditions.checkNotNull(type, "Null type");
  }

  private final StringMap<StringSet> permittedChildren = CollectionUtils.createStringMap();
  private final StringMap<StringMap<StringSet>> permittedAttrs = CollectionUtils.createStringMap();
  private final StringMap<PermittedCharacters> textPermitted = CollectionUtils.createStringMap();
  private final StringMap<List<String>> requiredInitial = CollectionUtils.createStringMap();

  public void addRequiredInitial(String key, List<String> list) {
    requiredInitial.put(key, list);
  }

  public void containsBlipText(String ... types) {
    for (String type : types) {
      type = fixType(type);
      textPermitted.put(type, PermittedCharacters.BLIP_TEXT);
    }
  }

  public void containsAnyText(String ... types) {
    for (String type : types) {
      type = fixType(type);
      textPermitted.put(type, PermittedCharacters.ANY);
    }
  }

  public void addChildren(String parentType, String ... childTypes) {
    parentType = fixType(parentType);
    StringSet permitted = permittedChildren.get(parentType);
    if (permitted == null) {
      permittedChildren.put(parentType, permitted = CollectionUtils.createStringSet());
    }
    for (String childType : childTypes) {
      checkNotTopLevel(childType);
      permitted.add(childType);
    }
  }

  public void addAttrs(String type, String ... attrNames) {
    checkNotTopLevel(type);
    for (String name : attrNames) {
      addAttrWithValues(type, name);
    }
  }

  public void addAttrWithValues(String type, String attrName, String ... permittedValues) {
    checkNotTopLevel(type);
    StringMap<StringSet> attrs = permittedAttrs.get(type);
    if (attrs == null) {
      permittedAttrs.put(type, attrs = CollectionUtils.createStringMap());
    }

    if (permittedValues.length == 0) {
      attrs.put(attrName, null);
    } else {
      StringSet values = attrs.get(attrName);
      if (values == null) {
        attrs.put(attrName, values = CollectionUtils.createStringSet());
      }

      for (String value : permittedValues) {
        values.add(value);
      }
    }
  }

  @Override
  public boolean permitsAttribute(String type, String attr) {
    checkNotTopLevel(type);
    StringMap<StringSet> attrs = permittedAttrs.get(type);
    return attrs != null && (attrs.containsKey(attr));
  }

  @Override
  public boolean permitsAttribute(String type, String attr, String value) {
    checkNotTopLevel(type);
    StringMap<StringSet> attrs = permittedAttrs.get(type);
    return attrs != null && attrs.containsKey(attr) &&
        (attrs.get(attr) == null || attrs.get(attr).contains(value));
  }

  @Override
  public boolean permitsChild(String parentType, String childType) {
    parentType = fixType(parentType);
    checkNotTopLevel(childType);
    StringSet permitted = permittedChildren.get(parentType);
    return permitted != null && permitted.contains(childType);
  }

  @Override
  public PermittedCharacters permittedCharacters(String typeOrNull) {
    typeOrNull = fixType(typeOrNull);
    PermittedCharacters permitted = textPermitted.get(typeOrNull);
    return permitted != null ? permitted : PermittedCharacters.NONE;
  }

  @Override
  public List<String> getRequiredInitialChildren(String type) {
    type = fixType(type);
    return requiredInitial.containsKey(type)
        ? requiredInitial.get(type) : Collections.<String>emptyList();
  }
}
TOP

Related Classes of org.waveprotocol.wave.model.schema.AbstractXmlSchemaConstraints

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.