Package com.google.wave.api.robot

Source Code of com.google.wave.api.robot.RobotCapabilitiesParser

/**
* 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 com.google.wave.api.robot;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.wave.api.Context;
import com.google.wave.api.ProtocolVersion;
import com.google.wave.api.event.EventType;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Map;

/**
* RobotCapabilityParser is responsible for parsing Robot's capabilities.xml
* file.
*
*/
public class RobotCapabilitiesParser {

  private static final Namespace XML_NS =
      Namespace.getNamespace("w", "http://wave.google.com/extensions/robots/1.0");

  private static final String CAPABILITIES_TAG = "capabilities";
  private static final String CAPABILITY_TAG = "capability";
  private static final String CAPABILITY_CONTEXT_ATTRIBUTE = "context";
  private static final String CAPABILITY_FILTER_ATTRIBUTE = "filter";
  private static final String CAPABILITY_NAME_ATTRIBUTE = "name";

  private static final String ROBOT_VERSION_TAG = "version";
  private static final String PROTOCOL_VERSION_TAG = "protocolversion";
  private static final String CONSUMER_KEYS_TAG = "consumer_keys";
  private static final String CONSUMER_KEY_TAG = "consumer_key";
  private static final String CONSUMER_KEY_FOR_ATTRIBUTE = "for";

  private final String capabilitiesXmlUrl;

  private final Map<EventType, Capability> capabilities;

  private final RobotConnection connection;

  private String capabilitiesHash;

  private ProtocolVersion protocolVersion;

  private String consumerKey;  // null if no consumer key

  private final String activeRobotApiUrl;

  public RobotCapabilitiesParser(String capabilitiesXmlUrl, RobotConnection connection,
      String activeRobotApiUrl)
      throws CapabilityFetchException {
    this.capabilitiesXmlUrl = capabilitiesXmlUrl;
    this.activeRobotApiUrl = activeRobotApiUrl;
    this.capabilities = Maps.newHashMap();
    this.connection = connection;
    parseRobotDescriptionXmlFile();
  }

  public Map<EventType, Capability> getCapabilities() {
    return capabilities;
  }

  public String getCapabilitiesHash() {
    return capabilitiesHash;
  }

  public ProtocolVersion getProtocolVersion() {
    return protocolVersion;
  }

  public String getConsumerKey() {
    return consumerKey;
  }

  private void parseRobotDescriptionXmlFile() throws CapabilityFetchException {
    // Fetch the XML file that defines the Robot capabilities.
    try {
      String xmlContent = connection.get(capabilitiesXmlUrl);
      if (xmlContent == null || xmlContent.isEmpty()) {
        throw new CapabilityFetchException("Empty capabilities.xml");
      }
      StringReader reader = new StringReader(xmlContent);
      Document document = new SAXBuilder().build(reader);

      // Parse all "<w:capability>" tags.
      List<Element> capabilities = getElements(document, CAPABILITIES_TAG, CAPABILITY_TAG, XML_NS);
      for (Element capability : capabilities) {
        parseCapabilityTag(capability);
      }

      // Always react to SELF_ADDED:
      if (!this.capabilities.containsKey(EventType.WAVELET_SELF_ADDED)) {
        this.capabilities.put(EventType.WAVELET_SELF_ADDED,
            new Capability(EventType.WAVELET_SELF_ADDED, Capability.DEFAULT_CONTEXT));
      }

      // Parse "<w:version>" tag.
      Element capabilitiesHashElement =
          document.getRootElement().getChild(ROBOT_VERSION_TAG, XML_NS);
      if (capabilitiesHashElement != null) {
        capabilitiesHash = capabilitiesHashElement.getText();
      }

      // Parse "<w:protocolversion>" tag.
      Element protocolVersionElement =
          document.getRootElement().getChild(PROTOCOL_VERSION_TAG, XML_NS);
      if (protocolVersionElement != null) {
        protocolVersion = ProtocolVersion.fromVersionString(protocolVersionElement.getText());
      } else {
        // In V1 API, we don't have <w:protocolversion> tag in the
        // capabilities.xml file.
        protocolVersion = ProtocolVersion.V1;
      }

      // Parse "<w:consumer_key>" tag(s).
      for (Element consumerKeyElement : getElements(document, CONSUMER_KEYS_TAG, CONSUMER_KEY_TAG,
          XML_NS)) {
        String forUrl = consumerKeyElement.getAttributeValue(CONSUMER_KEY_FOR_ATTRIBUTE);
        if (forUrl != null && forUrl.equals(activeRobotApiUrl)) {
          consumerKey = consumerKeyElement.getText();
        }
      }
    } catch (IOException iox) {
      throw new CapabilityFetchException("Failure reading capabilities for: " + capabilitiesXmlUrl,
          iox);
    } catch (JDOMException jdomx) {
      throw new CapabilityFetchException("Failure parsing capabilities for: " + capabilitiesXmlUrl,
          jdomx);
    } catch (RobotConnectionException e) {
      throw new CapabilityFetchException(e);
    }
  }

  private void parseCapabilityTag(Element capability) {
    // Get the event type.
    EventType eventType = EventType.valueOfIgnoreCase(
        capability.getAttributeValue(CAPABILITY_NAME_ATTRIBUTE));
    if (eventType == EventType.UNKNOWN) {
      return;
    }

    // Parse comma separated "context" attribute.
    List<Context> contexts;
    String contextsString = capability.getAttributeValue(CAPABILITY_CONTEXT_ATTRIBUTE);
    if (contextsString != null && !contextsString.isEmpty()) {
      try {
        contexts = Lists.newArrayList();
        for (String context : contextsString.split(",")) {
          contexts.add(Context.valueOfIgnoreCase(context));
        }
      } catch (IllegalArgumentException e) {
        contexts = Capability.DEFAULT_CONTEXT;
      }
    } else {
      contexts = Capability.DEFAULT_CONTEXT;
    }
    // Parse optional "filter" attribute.
    String filter = capability.getAttributeValue(CAPABILITY_FILTER_ATTRIBUTE);
    if (filter == null || filter.isEmpty()) {
      filter = "";
    }

    this.capabilities.put(eventType, new Capability(eventType, contexts, filter));
  }

  @SuppressWarnings({"cast", "unchecked"})
  private List<Element> getElements(Document doc, String parentTag, String tag, Namespace ns) {
    Element parent = doc.getRootElement().getChild(parentTag, ns);
    return (List<Element>) (parent == null ? Lists.newArrayList() : parent.getChildren(tag, ns));
  }
}
TOP

Related Classes of com.google.wave.api.robot.RobotCapabilitiesParser

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.