Package org.trzcinka.intellitrac.gateway.xmlrpc

Source Code of org.trzcinka.intellitrac.gateway.xmlrpc.XmlRpcTracGateway

/*
* Copyright 2008 Michal Trzcinka
*
* 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 org.trzcinka.intellitrac.gateway.xmlrpc;

import com.intellij.openapi.diagnostic.Logger;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.apache.xmlrpc.client.XmlRpcCommonsTransportFactory;
import org.trzcinka.intellitrac.dto.Attachment;
import org.trzcinka.intellitrac.dto.ConnectionSettings;
import org.trzcinka.intellitrac.dto.Ticket;
import org.trzcinka.intellitrac.dto.TicketChange;
import org.trzcinka.intellitrac.gateway.ConnectionFailedException;
import org.trzcinka.intellitrac.gateway.TracError;
import org.trzcinka.intellitrac.gateway.TracGateway;
import org.trzcinka.intellitrac.model.IntelliTracConfiguration;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* TracGateway implementation. Uses XML-RPC protocol to communicate with Trac.
*/
public class XmlRpcTracGateway implements TracGateway {
  private static final Logger logger = Logger.getInstance(XmlRpcTracGateway.class.getName());

  private static final Object[] EMPTY_ARRAY = new Object[]{};

  private static TracGateway instance;

  private XmlRpcClient client;

  private boolean configurationSet;

  /**
   * Hidden constructor.
   */
  private XmlRpcTracGateway() {
  }

  public static TracGateway getInstance() {
    if (instance == null) {
      instance = new XmlRpcTracGateway();
    }
    return instance;
  }

  public void testConnection(ConnectionSettings settings) throws ConnectionFailedException, MalformedURLException {
    try {
      XmlRpcClient xmlRpcClient = prepareClient(settings);
      xmlRpcClient.execute("system.listMethods", EMPTY_ARRAY);
    } catch (XmlRpcException e) {
      handleException(e);
    }
  }

  private XmlRpcClient prepareClient(ConnectionSettings settings) throws MalformedURLException {
    XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
    String suffix = IntelliTracConfiguration.getInstance().getConfiguration().getString("xmlrpc_suffix");
    config.setServerURL(new URL(StringUtils.removeEnd(settings.getTracUrl(), "/") + suffix));

    XmlRpcClient xmlRpcClient = new XmlRpcClient();
    xmlRpcClient.setConfig(config);
    XmlRpcCommonsTransportFactory transportFactory = new XmlRpcCommonsTransportFactory(xmlRpcClient);
    Credentials credentials = new UsernamePasswordCredentials(settings.getLogin(), settings.getPassword());
    HttpClient httpClient = new HttpClient();
    httpClient.getState().setCredentials(AuthScope.ANY, credentials);

    transportFactory.setHttpClient(httpClient);
    xmlRpcClient.setTransportFactory(transportFactory);
    return xmlRpcClient;
  }

  private XmlRpcClient retrieveClient() throws ConnectionFailedException {
    if (!configurationSet) {
      throw new ConnectionFailedException("Could not connect to Trac server on startup. Verify your settings.");
    }
    assert client != null;
    return client;
  }

  /**
   * Sets the given configuration.
   *
   * @param settings settings.
   * @throws MalformedURLException when provided configuration URL is malformed.
   */
  public void setConfiguration(ConnectionSettings settings) throws MalformedURLException {
    client = prepareClient(settings);
    configurationSet = true;
  }

  public List<Ticket> retrieveTickets(String query) throws ConnectionFailedException, TracError {
    List<Ticket> result = null;
    try {
      Object response = retrieveClient().execute("ticket.query", new Object[]{query});
      Integer[] ticketIdsList = CastUtils.castArray((Object[]) response, Integer.class);
      result = new ArrayList<Ticket>(ticketIdsList.length);
      for (Integer id : ticketIdsList) {
        result.add(retrieveTicket(id));
      }
    } catch (XmlRpcException e) {
      handleException(e);
    }
    return result;
  }

  public Ticket retrieveTicket(int ticketId) throws ConnectionFailedException, TracError {
    Ticket ticket = null;
    try {
      Object response = retrieveClient().execute("ticket.get", new Object[]{ticketId});
      ticket = new TicketAdapter(response);
      ticket.setChanges(retrieveTicketChanges(ticketId));
      ticket.setAttachments(retrieveAttachments(ticketId));
    } catch (XmlRpcException e) {
      handleException(e);
    }
    return ticket;
  }

  private List<TicketChange> retrieveTicketChanges(int ticketId) throws ConnectionFailedException, XmlRpcException {
    Object[] responses = (Object[]) retrieveClient().execute("ticket.changeLog", new Object[]{ticketId});
    List<TicketChange> result = new ArrayList<TicketChange>(responses.length);
    for (Object response : responses) {
      TicketChangeAdapter change = new TicketChangeAdapter((Object[]) response);
      if (!(TicketChangeAdapter.COMMENT.equals(change.getField()) && StringUtils.isEmpty(change.getNewValue()))) {
        result.add(change);
      }
    }
    return result;
  }

  public List<String> retrieveComponents() throws ConnectionFailedException, TracError {
    return retrieveStringsList("ticket.component.getAll");
  }

  public List<String> retrievePriorities() throws ConnectionFailedException, TracError {
    return retrieveStringsList("ticket.priority.getAll");
  }

  public List<String> retrieveTypes() throws ConnectionFailedException, TracError {
    return retrieveStringsList("ticket.type.getAll");
  }

  public List<String> retrieveMilestones() throws ConnectionFailedException, TracError {
    return retrieveStringsList("ticket.milestone.getAll");
  }

  public List<String> retrieveVersions() throws ConnectionFailedException, TracError {
    return retrieveStringsList("ticket.version.getAll");
  }

  public List<String> retrieveResolutions() throws ConnectionFailedException, TracError {
    return retrieveStringsList("ticket.resolution.getAll");
  }

  public void updateTicket(Ticket ticket, String comment) throws ConnectionFailedException, TracError {
    try {
      retrieveClient().execute("ticket.update", (Object[]) TicketAdapter.unadaptEditedTicket(ticket, comment));
    } catch (XmlRpcException e) {
      handleException(e);
    }
  }

  public Integer saveTicket(Ticket ticket) throws ConnectionFailedException, TracError {
    Integer result = null;
    try {
      result = (Integer) retrieveClient().execute("ticket.create", (Object[]) TicketAdapter.unadaptNewTicket(ticket));
    } catch (XmlRpcException e) {
      handleException(e);
    }
    return result;
  }

  public byte[] retrieveAttachment(int ticketId, String fileName) throws ConnectionFailedException, TracError {
    byte[] result = null;
    try {
      result = (byte[]) retrieveClient().execute("ticket.getAttachment", new Object[]{ticketId, fileName});
    } catch (XmlRpcException e) {
      handleException(e);
    }
    return result;
  }

  public void saveAttachment(int ticketId, File attachment, String description, boolean replace) throws ConnectionFailedException, TracError {
    byte[] data;
    try {
      data = FileUtils.readFileToByteArray(attachment);
    } catch (IOException e) {
      logger.error("Couldn't get data from file", e);

      throw new TracError(e);
    }
    try {
      retrieveClient().execute("ticket.putAttachment", new Object[]{ticketId, attachment.getName(), description, data, replace});
    } catch (XmlRpcException e) {
      handleException(e);
    }
  }

  public String wikiToHtml(String rawText) throws ConnectionFailedException, TracError {
    String result = null;
    try {
      Object response = retrieveClient().execute("wiki.wikiToHtml", new Object[]{rawText == null ? StringUtils.EMPTY : rawText});
      result = (String) response;
    } catch (XmlRpcException e) {
      handleException(e);
    }
    return result;
  }

  private List<Attachment> retrieveAttachments(int ticketId) throws ConnectionFailedException, TracError {
    List<Attachment> result = new ArrayList<Attachment>();
    try {
      Object response = retrieveClient().execute("ticket.listAttachments", new Object[]{ticketId});
      Object[] array = (Object[]) response;
      for (Object o : array) {
        Attachment attachment = new AttachmentAdapter(o);
        result.add(attachment);
      }
    } catch (XmlRpcException e) {
      handleException(e);
    }
    return result;
  }

  private List<String> retrieveStringsList(String functionName) throws ConnectionFailedException {
    List<String> result = null;
    try {
      Object response = retrieveClient().execute(functionName, EMPTY_ARRAY);
      String[] array = CastUtils.castArray((Object[]) response, String.class);
      result = Arrays.asList(array);
    } catch (XmlRpcException e) {
      handleException(e);
    }
    return result;
  }

  private void handleException(XmlRpcException e) throws ConnectionFailedException {
    throw new ConnectionFailedException(e);
  }

}
TOP

Related Classes of org.trzcinka.intellitrac.gateway.xmlrpc.XmlRpcTracGateway

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.