Package org.eclipse.ecf.internal.provider.xmpp.search

Source Code of org.eclipse.ecf.internal.provider.xmpp.search.XMPPUserSearchManager

/*******************************************************************************
* Copyright (c) 2008 Marcelo Mayworm. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:   Marcelo Mayworm - initial API and implementation
*
******************************************************************************/
package org.eclipse.ecf.internal.provider.xmpp.search;

import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.identity.Namespace;
import org.eclipse.ecf.core.user.IUser;
import org.eclipse.ecf.core.user.User;
import org.eclipse.ecf.core.util.ECFException;
import org.eclipse.ecf.internal.provider.xmpp.Messages;
import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin;
import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnection;
import org.eclipse.ecf.presence.search.AbstractUserSearchManager;
import org.eclipse.ecf.presence.search.ICriteria;
import org.eclipse.ecf.presence.search.ICriterion;
import org.eclipse.ecf.presence.search.IRestriction;
import org.eclipse.ecf.presence.search.IResultList;
import org.eclipse.ecf.presence.search.ISearch;
import org.eclipse.ecf.presence.search.IUserSearchEvent;
import org.eclipse.ecf.presence.search.IUserSearchListener;
import org.eclipse.ecf.presence.search.IUserSearchManager;
import org.eclipse.ecf.presence.search.ResultList;
import org.eclipse.ecf.presence.search.UserSearchCompleteEvent;
import org.eclipse.ecf.presence.search.UserSearchException;
import org.eclipse.ecf.provider.xmpp.identity.XMPPID;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
import org.jivesoftware.smackx.ReportedData;
import org.jivesoftware.smackx.ReportedData.Row;
import org.jivesoftware.smackx.search.UserSearch;

/**
* A specific implementation for XMPP provider. XEP-0055:
* http://www.xmpp.org/extensions/xep-0055.html
*
* @see IUserSearchManager
* @since 3.0
*/
public class XMPPUserSearchManager extends AbstractUserSearchManager {

  /** Search service name on XMPP server */
  protected static final String SERVICE_SEARCH = "search."; //$NON-NLS-1$

  /** Wrapper for XMPP connection */
  protected ECFConnection ecfConnection;

  protected Namespace connectNamespace;

  protected ID connectedID;

  protected Form form;

  protected UserSearch manager;

  protected boolean enabled;

  protected ICriteria criteria;

  protected static final String FORM_TYPE = "FORM_TYPE"; //$NON-NLS-1$

  protected static final String NAME = "name"; //$NON-NLS-1$

  protected static final String JID = "jid"; //$NON-NLS-1$

  protected static final String SEARCH_ACTION = "search"; //$NON-NLS-1$

  public XMPPUserSearchManager() {
    manager = new UserSearch();
  }

  /**
   * Create a specific {@link ICriteria} for XMPP
   */
  public ICriteria createCriteria() {
    return new XMPPCriteria();
  }

  /**
   * Create a specific {@link IRestriction} for XMPP
   */
  public IRestriction createRestriction() {
    return new XMPPSelection();
  }

  /**
   * Specific implementation for XMPP
   *
   * @see IUserSearchManager#search(ICriteria).
   */
  public ISearch search(ICriteria criteria) throws UserSearchException {

    ResultList resultList = new ResultList();
    try {
      // initialize the form by chance it is null
      if (form == null)
        form = manager.getSearchForm(ecfConnection.getXMPPConnection(),
            SERVICE_SEARCH
                + ecfConnection.getXMPPConnection()
                    .getServiceName());

      /*
       * For XMPP criterion is considered. The XMPP server will deal with
       * the search.
       */
      List criterions = criteria.getCriterions();
      // add the fields for the search dynamically
      // consider just the fields used on the search
      // fields checked by user

      String fields[] = getUserPropertiesFields();
      for (int i = 0; i < fields.length; i++) {
        Iterator criterionsIterator = criterions.iterator();
        // for each user properties field check if it
        // was added by user for the criteria
        // for each field, a search is performed, and
        // the partial result is added to the result list
        while (criterionsIterator.hasNext()) {
          ICriterion criterion = (ICriterion) criterionsIterator
              .next();
          if (criterion.equals(fields[i])) {
            Form answerForm = form.createAnswerForm();
            answerForm.setAnswer(fields[i], true);
            answerForm.setAnswer(SEARCH_ACTION, criterion
                .toExpression());
            ReportedData data = manager.sendSearchForm(
                ecfConnection.getXMPPConnection(), answerForm,
                SERVICE_SEARCH
                    + ecfConnection.getXMPPConnection()
                        .getServiceName());
            // create a result list from ReportedData
            IResultList partialResultList = createResultList(data);
            resultList.addAll(partialResultList.getResults());
          }
        }
      }

      return new XMPPSearch(resultList);

    } catch (final XMPPException e) {
      String message = null;
      if (e.getXMPPError() != null && e.getXMPPError().getCode() == 404) {
        message = Messages.XMPPContainer_UNRECOGONIZED_SEARCH_SERVICE;
      } else {
        message = e.getLocalizedMessage();
      }
      throw new UserSearchException(message, e, criteria);
    } catch (ECFException e) {
      throw new UserSearchException(e, criteria);
    }

  }

  /**
   * Create a result list from ReportedData. Identify dynamically columns and
   * rows and create users adding it to a {@link IResultList}
   *
   * @param data
   *            ReportedData
   * @return {@link IResultList} a list of users
   * @throws
   */
  protected IResultList createResultList(ReportedData data) {
    ResultList result = new ResultList();
    Iterator rows = data.getRows();
    while (rows.hasNext()) {
      Row row = (Row) rows.next();
      Iterator jids = row.getValues(JID);
      Iterator names = row.getValues(NAME);
      String jid = null;
      String name = null;
      // XMPP server returns the same length for both
      while (jids.hasNext() && names.hasNext()) {
        try {
          jid = (String) jids.next();
          name = (String) names.next();
          IUser user = new User(new XMPPID(connectNamespace, jid),
              name);
          result.add(new XMPPResultItem(user));
        } catch (URISyntaxException e) {
          throw new RuntimeException(
              "cannot create connect id for client " + jid //$NON-NLS-1$
                  + " , name = " + name, e); //$NON-NLS-1$
        }
      }
    }
    return result;
  }

  /**
   * Specific implementation for XMPP
   *
   * @see IUserSearchManager#search(ICriteria, IUserSearchListener)
   */
  public void search(final ICriteria criteria, final IUserSearchListener listener) {
    Assert.isNotNull(criteria);
    Assert.isNotNull(listener);
    Job job = new Job(Messages.XMPPUserSearchManager_JOB) {
      protected IStatus run(IProgressMonitor monitor) {
        try {
          ISearch search = search(criteria);
          UserSearchCompleteEvent complete = new UserSearchCompleteEvent(
              search);
          listener.handleUserSearchEvent(complete);
        } catch (UserSearchException e) {
          log(e.getLocalizedMessage(), e);
          return new Status(IStatus.ERROR,XmppPlugin.PLUGIN_ID,IStatus.ERROR,"Exception in user search",e);
        }
        return Status.OK_STATUS;
      }
    };
    job.schedule();
  }

  /**
   * These parameters must be not null
   *
   * @param connectNamespace
   * @param connectedID
   * @param connection
   */
  public void setConnection(Namespace connectNamespace, ID connectedID,
      ECFConnection connection) {
    Assert.isNotNull(connectNamespace);
    Assert.isNotNull(connectedID);
    Assert.isNotNull(connection);
    this.connectNamespace = connectNamespace;
    this.connectedID = connectedID;
    this.ecfConnection = connection;
  }

  /**
   * Returns the user properties fields available on the XMPP server
   *
   * @param form
   * @return String[] fields for form
   * @throws ECFException
   */
  public String[] getUserPropertiesFields() throws ECFException {
    try {
      if (form == null)
        form = manager.getSearchForm(ecfConnection.getXMPPConnection(),
            SERVICE_SEARCH
                + ecfConnection.getXMPPConnection()
                    .getServiceName());

      Set fields = new HashSet();
      Iterator userProperties = form.getFields();
      while (userProperties.hasNext()) {
        FormField field = (FormField) userProperties.next();
        String variable = field.getVariable();
        // ignore these fields
        if (!variable.equalsIgnoreCase(FORM_TYPE)
            && !variable.equalsIgnoreCase(SEARCH_ACTION))
          fields.add(variable);
      }
      return (String[]) fields.toArray(new String[0]);
    } catch (final XMPPException e) {
      String message = null;
      if (e.getXMPPError() != null && e.getXMPPError().getCode() == 404) {
        message = Messages.XMPPContainer_UNRECOGONIZED_SEARCH_SERVICE;
      } else {
        message = e.getLocalizedMessage();
      }
      throw new ECFException(message, e);
    }

  }

  /**
   * Notify that user search for XMPP is enabled
   */
  public boolean isEnabled() {
    return this.enabled;
  }

  /**
   * For gtalk it should be not enabled
   *
   * @param enabled
   */
  public void setEnabled(boolean enabled) {
    this.enabled = enabled;
  }

  // utility methods
  protected void log(String msg, Throwable e) {
    XmppPlugin.log(msg, e);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.eclipse.ecf.presence.search.AbstractUserSearchManager#fireUserSearchEvent
   * (org.eclipse.ecf.presence.search.IUserSearchEvent)
   */
  public void fireUserSearchEvent(IUserSearchEvent event) {
    super.fireUserSearchEvent(event);
  }

}
TOP

Related Classes of org.eclipse.ecf.internal.provider.xmpp.search.XMPPUserSearchManager

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.