Package org.dbwiki.web.request

Source Code of org.dbwiki.web.request.URLDecodingRules

package org.dbwiki.web.request;

import java.util.Hashtable;
import java.util.StringTokenizer;

import org.dbwiki.data.database.Database;
import org.dbwiki.data.database.DatabaseAttributeNode;
import org.dbwiki.data.database.DatabaseElementList;
import org.dbwiki.data.database.DatabaseGroupNode;
import org.dbwiki.data.database.DatabaseTextNode;

import org.dbwiki.data.index.DatabaseEntry;

import org.dbwiki.data.resource.ResourceIdentifier;

import org.dbwiki.data.schema.AttributeSchemaNode;
import org.dbwiki.data.schema.GroupSchemaNode;
import org.dbwiki.data.schema.DatabaseSchema;
import org.dbwiki.data.schema.SchemaNode;

import org.dbwiki.exception.data.WikiDataException;
import org.dbwiki.exception.data.WikiSchemaException;

import org.dbwiki.web.request.parameter.RequestParameterVersion;

public class URLDecodingRules {

  /*
   * Private Variables
   */
 
  private Hashtable<Integer, URLDecodingRule> _rules;
 
  /*
   * Constructors
   */
 
  public URLDecodingRules(DatabaseSchema schema, String definition) throws org.dbwiki.exception.WikiException {
   
    _rules = new Hashtable<Integer, URLDecodingRule>();
   
    StringTokenizer tokens = new StringTokenizer(definition, " \t\n\r\f,");
   
    while (tokens.hasMoreTokens()) {
      if  (tokens.nextToken().equalsIgnoreCase("IDENTIFY")) {
        try {
          String path = tokens.nextToken();
          if (tokens.nextToken().equalsIgnoreCase("BY")) {
            SchemaNode node = schema.get(path);
            if (node.isGroup()) {
              String value = tokens.nextToken();
              String valuePath = path;
              if (!valuePath.endsWith(SchemaNode.SchemaPathSeparator)) {
                valuePath = valuePath + SchemaNode.SchemaPathSeparator + value;
              } else {
                valuePath = valuePath + value;
              }
              SchemaNode valueNode = schema.get(valuePath);
              if (valueNode.isAttribute()) {
                this.add(new URLDecodingRule((GroupSchemaNode)node, (AttributeSchemaNode)valueNode));
              } else {
                throw new WikiSchemaException(WikiSchemaException.InvalidConstraintDefinition, valueNode + " is not an attribute node");
              }
            } else {
              throw new WikiSchemaException(WikiSchemaException.InvalidConstraintDefinition, path + " is not a group node");
            }
          } else {
            throw new WikiSchemaException(WikiSchemaException.InvalidConstraintDefinition, definition);
          }
        } catch (java.util.NoSuchElementException noSuchElementException) {
          throw new WikiSchemaException(WikiSchemaException.InvalidConstraintDefinition, definition);
        }
      } else {
        throw new WikiSchemaException(WikiSchemaException.InvalidConstraintDefinition, definition);
      }
    }
  }
 
 
  /*
   * Public Methods
   */
 
  public void add(URLDecodingRule rule) throws org.dbwiki.exception.WikiException {
    Integer key = new Integer(rule.node().id());
    if (!_rules.containsKey(key)) {
      _rules.put(key, rule);
    } else {
      throw new WikiSchemaException(WikiSchemaException.InvalidConstraintDefinition, "Duplicate constraint for node " + rule.node());
    }
  }
 
  public ResourceIdentifier decode(Database database, RequestURL url, RequestParameterVersion versionParameter) throws org.dbwiki.exception.WikiException {
   
    // FORMAT: {/[<label>:<key-value>|<key-value>]}+ /[<label>|<label>:<key-value>|<key-value>]

    GroupSchemaNode root = database.schema().root();
    URLDecodingRule rule = this.get(root);
    if (rule != null) {
      String entryIdentifier = url.get(0).decodedText();
      int pos = entryIdentifier.indexOf(':');
      if (pos != -1) {
        if (entryIdentifier.substring(0, pos).equals(root.label())) {
          entryIdentifier = entryIdentifier.substring(pos + 1);
        } else {
          throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
        }
      }
      DatabaseEntry entry = database.content().get(entryIdentifier);
      if (entry != null) {
        if (url.size() > 1) {
          return this.decode(database, (DatabaseGroupNode)database.get(entry.identifier()), versionParameter, url, 1);
        } else {
          return entry.identifier();
        }
      } else {
        throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
      }
    } else {
      throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
    }
  }
 
  public URLDecodingRule get(int index) {
    return _rules.get(index);
  }
 
  public URLDecodingRule get(SchemaNode node) {
    return _rules.get(new Integer(node.id()));
  }
 
  public String printConstraints() {
   
    String text = "";
   
    for (URLDecodingRule rule : _rules.values()) {
      String line = "IDENTIFY " + rule.node().path() + " BY " + rule.value().path().substring(rule.node().path().length() + 1);
      if (text.equals("")) {
        text = line;
      } else {
        text = text + ",\n" + line;
      }
    }
    return text;
  }
 
  public int size() {
    return _rules.size();
  }
 
 
  /*
   * Private Methods
   */
 
  public ResourceIdentifier decode(Database database, DatabaseGroupNode node, RequestParameterVersion versionParameter, RequestURL url, int pathIndex) throws org.dbwiki.exception.WikiException {
   
    // FORMAT: {/[<label>:<key-value>|<key-value>]}+ /[<label>|<label>:<key-value>|<key-value>]

    GroupSchemaNode schemaNode = (GroupSchemaNode)node.schema();
    String nodeIdentifier = url.get(pathIndex).decodedText();
   
    URLDecodingRule rule = null;
    String keyValue = nodeIdentifier;
   
    int pos = nodeIdentifier.indexOf(':');

    if (pos != -1) {
      String nodeLabel = nodeIdentifier.substring(0, pos);
      rule = this.get(schemaNode.children().get(nodeLabel));
      keyValue = nodeIdentifier.substring(pos + 1);
    } else {
      // If it's the last element of the URL path the nodeIdentifier could be the node label
      // of an attribute node or a key value for an internal node.
      // First check whether the nodeIdentifier is a valid node label for the current
      // schema node.
      for (int iChild = 0; iChild < schemaNode.children().size(); iChild++) {
        SchemaNode childSchema = schemaNode.children().get(iChild);
        if ((childSchema.label().equals(nodeIdentifier)) && (childSchema.isAttribute())) {
          // Make sure that there is only one child
          DatabaseElementList nodes = node.find(childSchema.path().substring(node.schema().path().length() + 1));
          if (nodes.size() > 1) {
            throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
          } else if (nodes.size() == 1) {
            if (pathIndex == (url.size() - 1)) {
              return nodes.get(0).identifier();
            } else {
              return this.decode(database, (DatabaseGroupNode)nodes.get(0), versionParameter, url, pathIndex + 1);
            }
          } else {
            throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
          }
        }
      }
      // This part of the code is only reached if the nodeIdentifier does not point
      // to an attribute node. There should only be one schema node child with a rule defined
      // for that node.
      for (int iChild = 0; iChild < schemaNode.children().size(); iChild++) {
        URLDecodingRule childRule = this.get(schemaNode.children().get(iChild));
        if (childRule != null) {
          if (rule == null) {
            rule = childRule;
          } else {
            throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
          }
        }
      }
    }

    if (rule != null) {
      DatabaseElementList nodes = node.find(rule.node().path().substring(node.schema().path().length() + 1));
      DatabaseGroupNode nextNode = null;
      for (int iNode = 0; iNode < nodes.size(); iNode++) {
        DatabaseGroupNode childNode = (DatabaseGroupNode)nodes.get(iNode);
        if (versionParameter.matches(childNode)) {
          int matches = 0;
          DatabaseElementList valueNodes = childNode.find(rule.value().path().substring(childNode.schema().path().length() + 1));
          for (int iValueNode = 0; iValueNode < valueNodes.size(); iValueNode++) {
            DatabaseAttributeNode attributeNode = (DatabaseAttributeNode)valueNodes.get(iValueNode);
            for (int iAttrValue = 0; iAttrValue < attributeNode.value().size(); iAttrValue++) {
              DatabaseTextNode textNode = attributeNode.value().get(iAttrValue);
              if ((versionParameter.matches(textNode)) && (textNode.value().equals(keyValue))) {
                matches++;
                break;
              }
            }
          }
          if (matches == 1) {
            if (nextNode == null) {
              nextNode = childNode;
            } else {
              throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
            }
          }
        }
      }
      if (nextNode != null) {
        if (pathIndex == (url.size() - 1)) {
          return nextNode.identifier();
        } else {
          return this.decode(database, nextNode, versionParameter, url, pathIndex + 1);
        }
      } else {
        throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
      }
    } else {
      throw new WikiDataException(WikiDataException.UnknownResource, url.toString());
    }
   
  }
}
TOP

Related Classes of org.dbwiki.web.request.URLDecodingRules

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.