Package org.eclipse.php.internal.debug.core.pathmapper

Source Code of org.eclipse.php.internal.debug.core.pathmapper.PathMapper$Mapping

/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* 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:
*     IBM Corporation - initial API and implementation
*     Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.debug.core.pathmapper;

import java.io.File;
import java.util.*;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.php.internal.core.util.preferences.IXMLPreferencesStorable;
import org.eclipse.php.internal.debug.core.pathmapper.PathEntry.Type;

public class PathMapper implements IXMLPreferencesStorable {

  private Map<VirtualPath, VirtualPath> remoteToLocalMap;
  private Map<VirtualPath, VirtualPath> localToRemoteMap;
  private Map<VirtualPath, Type> localToPathEntryType;

  public PathMapper() {
    remoteToLocalMap = new HashMap<VirtualPath, VirtualPath>();
    localToRemoteMap = new HashMap<VirtualPath, VirtualPath>();
    localToPathEntryType = new HashMap<VirtualPath, Type>();
  }

  public synchronized void addEntry(String remoteFile, PathEntry entry) {
    VirtualPath remotePath = new VirtualPath(remoteFile);
    VirtualPath localPath = entry.getAbstractPath().clone(); // don't break
                                  // original
                                  // entry
                                  // path

    // last segments must match!
    if (!remotePath.getLastSegment().equalsIgnoreCase(
        localPath.getLastSegment())) {
      return;
    }

    while (remotePath.getSegmentsCount() > 0
        && localPath.getSegmentsCount() > 1) { // local path is limited
                            // to have at least one
                            // segment
      if (!remotePath.getLastSegment().equalsIgnoreCase(
          localPath.getLastSegment())) {
        break;
      }
      remotePath.removeLastSegment();
      localPath.removeLastSegment();
    }
    if (!remotePath.equals(localPath)) {
      remoteToLocalMap.put(remotePath, localPath);
      localToRemoteMap.put(localPath, remotePath);
      localToPathEntryType.put(localPath, entry.getType());
    }
  }

  public synchronized void addServerEntry(String remoteFile, PathEntry entry) {
    VirtualPath localPath = entry.getAbstractPath().clone(); // don't break
                                  // original
                                  // entry
                                  // path
    remoteToLocalMap.put(localPath, localPath);
    localToRemoteMap.put(localPath, localPath);
    localToPathEntryType.put(localPath, entry.getType());
  }

  public String getRemoteFile(String localFile) {
    VirtualPath path = getPath(localToRemoteMap, new VirtualPath(localFile));
    if (path != null) {
      return path.toString();
    }
    return null;
  }

  /**
   * Returns exact mapping for the given remote path (if exists)
   *
   * @param remoteFile
   *            Remote path
   * @return virtual path
   */
  public VirtualPath getLocalPathMapping(VirtualPath remotePath) {
    return remoteToLocalMap.get(remotePath);
  }

  public PathEntry getLocalFile(String remoteFile) {
    VirtualPath path = getPath(remoteToLocalMap,
        new VirtualPath(remoteFile));
    if (path != null) {
      String localFile = path.toString();
      Type type = getPathType(path);
      if (type == Type.SERVER) {
        return null;
      } else if (type == Type.WORKSPACE) {
        IResource resource = ResourcesPlugin.getWorkspace().getRoot()
            .findMember(localFile);
        if (resource != null) {
          return new PathEntry(path, type, resource.getParent());
        }
      } else {
        File file = new File(localFile);
        if (file.exists()) {
          if (type == Type.INCLUDE_FOLDER || type == Type.INCLUDE_VAR) {
            return new PathEntry(path, type, null);
          }
          return new PathEntry(path, type, file.getParentFile());
        }
      }
    }
    return null;
  }

  public PathEntry getServerFile(String remoteFile) {
    VirtualPath tmp = new VirtualPath(remoteFile);
    for (VirtualPath path : remoteToLocalMap.keySet()) {
      if (localToPathEntryType.get(path) == Type.SERVER) {
        if (path.isPrefixOf(tmp)) {
          return new PathEntry(path, Type.SERVER, null);
        }
      }
    }
    return null;
  }

  protected VirtualPath getPath(Map<VirtualPath, VirtualPath> map,
      VirtualPath path) {
    path = path.clone();
    VirtualPath mapPath = null;
    List<String> strippedSegments = new LinkedList<String>();

    while (path.getSegmentsCount() > 0) {
      mapPath = map.get(path);
      if (mapPath != null) {
        mapPath = mapPath.clone();
        break;
      }
      strippedSegments.add(path.removeLastSegment());
    }
    // Check whether device is mapped (path contains only device):
    if (mapPath == null) {
      mapPath = map.get(path);
      if (mapPath != null) {
        mapPath = mapPath.clone();
      }
    }
    // Append all stripped segments to the result path:
    if (mapPath != null) {
      ListIterator<String> i = strippedSegments
          .listIterator(strippedSegments.size());
      while (i.hasPrevious()) {
        mapPath.addLastSegment(i.previous());
      }
    }
    return mapPath;
  }

  protected Type getPathType(VirtualPath path) {
    path = path.clone();
    while (path.getSegmentsCount() > 0) {
      Type type = localToPathEntryType.get(path);
      if (type != null) {
        return type;
      }
      path.removeLastSegment();
    }
    return null;
  }

  /**
   * Returns contents of this path mapper
   */
  public synchronized Mapping[] getMapping() {
    List<Mapping> l = new ArrayList<Mapping>(localToRemoteMap.size());
    Iterator<VirtualPath> i = localToRemoteMap.keySet().iterator();
    while (i.hasNext()) {
      VirtualPath localPath = i.next();
      VirtualPath remotePath = localToRemoteMap.get(localPath);
      Type type = localToPathEntryType.get(localPath);
      l.add(new Mapping(localPath, remotePath, type));
    }
    return l.toArray(new Mapping[l.size()]);
  }

  /**
   * Sets this path mapper contents removing any previous mappings
   */
  public synchronized void setMapping(Mapping[] mappings) {
    remoteToLocalMap.clear();
    localToRemoteMap.clear();
    localToPathEntryType.clear();

    for (Mapping mapping : mappings) {
      localToRemoteMap.put(mapping.localPath, mapping.remotePath);
      remoteToLocalMap.put(mapping.remotePath, mapping.localPath);
      localToPathEntryType.put(mapping.localPath, mapping.type);
    }
  }

  /**
   * Adds new mapping to this mapper
   */
  public synchronized void addMapping(Mapping mapping) {
    localToRemoteMap.put(mapping.localPath, mapping.remotePath);
    remoteToLocalMap.put(mapping.remotePath, mapping.localPath);
    localToPathEntryType.put(mapping.localPath, mapping.type);
  }

  /**
   * Removes mapping
   */
  public synchronized void removeMapping(Mapping mapping) {
    localToRemoteMap.remove(mapping.localPath);
    remoteToLocalMap.remove(mapping.remotePath);
    localToPathEntryType.remove(mapping.localPath);
  }

  public static class Mapping implements Cloneable {
    public VirtualPath localPath;
    public VirtualPath remotePath;
    public Type type;

    public Mapping() {
    }

    public Mapping(VirtualPath localPath, VirtualPath remotePath, Type type) {
      this.localPath = localPath;
      this.remotePath = remotePath;
      this.type = type;
    }

    public Mapping clone() {
      return new Mapping(localPath, remotePath, type);
    }

    public boolean equals(Object obj) {
      if (!(obj instanceof Mapping)) {
        return false;
      }
      Mapping other = (Mapping) obj;
      return other.localPath.equals(localPath)
          && other.remotePath.equals(remotePath)
          && other.type == type;
    }

    public int hashCode() {
      return localPath.hashCode() + 13 * remotePath.hashCode() + 31
          * type.hashCode();
    }

    public String toString() {
      StringBuilder buf = new StringBuilder("Mapping { "); //$NON-NLS-1$
      buf.append(localPath).append(", ").append(remotePath).append(", ") //$NON-NLS-1$ //$NON-NLS-2$
          .append(type);
      return buf.toString();
    }
  }

  @SuppressWarnings("unchecked")
  public synchronized void restoreFromMap(HashMap map) {
    if (map == null) {
      return;
    }
    remoteToLocalMap.clear();
    localToRemoteMap.clear();
    localToPathEntryType.clear();

    Iterator i = map.keySet().iterator();
    while (i.hasNext()) {
      HashMap entryMap = (HashMap) map.get(i.next());
      String localStr = (String) entryMap.get("local"); //$NON-NLS-1$
      String remoteStr = (String) entryMap.get("remote"); //$NON-NLS-1$
      String typeStr = (String) entryMap.get("type"); //$NON-NLS-1$
      if (localStr != null && remoteStr != null && typeStr != null) {
        Type type = Type.valueOf(typeStr);
        VirtualPath local = new VirtualPath(localStr);
        VirtualPath remote = new VirtualPath(remoteStr);
        remoteToLocalMap.put(remote, local);
        localToRemoteMap.put(local, remote);
        localToPathEntryType.put(local, type);
      }
    }
  }

  @SuppressWarnings("unchecked")
  public synchronized HashMap storeToMap() {
    HashMap entries = new HashMap();
    Iterator<VirtualPath> i = localToRemoteMap.keySet().iterator();
    int c = 1;
    while (i.hasNext()) {
      HashMap entry = new HashMap();
      VirtualPath local = i.next();
      VirtualPath remote = localToRemoteMap.get(local);
      Type type = localToPathEntryType.get(local);
      entry.put("local", local); //$NON-NLS-1$
      entry.put("remote", remote); //$NON-NLS-1$
      if (type != null) {
        entry.put("type", type.name()); //$NON-NLS-1$
      }
      entries.put("item" + (c++), entry); //$NON-NLS-1$
    }
    return entries;
  }
}
TOP

Related Classes of org.eclipse.php.internal.debug.core.pathmapper.PathMapper$Mapping

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.