You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hdt.apache.org by ad...@apache.org on 2013/01/08 23:26:26 UTC

[3/11] Import of source from Apache Hadoop MapReduce contrib, this is the plugin as it existed in the Hadoop 0.23.4 release.

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/ActionProvider.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/ActionProvider.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/ActionProvider.java
new file mode 100644
index 0000000..65436ac
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/ActionProvider.java
@@ -0,0 +1,193 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+import org.apache.hadoop.eclipse.ImageLibrary;
+import org.apache.hadoop.eclipse.actions.DFSActionImpl;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.ICommonActionConstants;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.ICommonMenuConstants;
+
+/**
+ * Allows the user to delete and refresh items in the DFS tree
+ */
+
+public class ActionProvider extends CommonActionProvider {
+
+  private static ICommonActionExtensionSite site;
+
+  public ActionProvider() {
+  }
+
+  /* @inheritDoc */
+  @Override
+  public void init(ICommonActionExtensionSite site) {
+    if (ActionProvider.site != null) {
+      System.err.printf("%s: Multiple init()\n", this.getClass()
+          .getCanonicalName());
+      return;
+    }
+    super.init(site);
+    ActionProvider.site = site;
+  }
+
+  /* @inheritDoc */
+  @Override
+  public void fillActionBars(IActionBars actionBars) {
+    actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),
+        new DFSAction(DFSActions.DELETE));
+    actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(),
+        new DFSAction(DFSActions.REFRESH));
+
+    if (site == null)
+      return;
+
+    if ((site.getStructuredViewer().getSelection() instanceof IStructuredSelection)
+        && (((IStructuredSelection) site.getStructuredViewer()
+            .getSelection()).size() == 1)
+        && (((IStructuredSelection) site.getStructuredViewer()
+            .getSelection()).getFirstElement() instanceof DFSFile)) {
+
+      actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN,
+          new DFSAction(DFSActions.OPEN));
+    }
+
+    actionBars.updateActionBars();
+  }
+
+  /* @inheritDoc */
+  @Override
+  public void fillContextMenu(IMenuManager menu) {
+    /*
+     * Actions on multiple selections
+     */
+    menu.appendToGroup(ICommonMenuConstants.GROUP_EDIT, new DFSAction(
+        DFSActions.DELETE));
+
+    menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN, new DFSAction(
+        DFSActions.REFRESH));
+
+    menu.appendToGroup(ICommonMenuConstants.GROUP_NEW, new DFSAction(
+        DFSActions.DOWNLOAD));
+
+    if (site == null)
+      return;
+
+    ISelection isel = site.getStructuredViewer().getSelection();
+    if (!(isel instanceof IStructuredSelection))
+      return;
+
+    /*
+     * Actions on single selections only
+     */
+
+    IStructuredSelection issel = (IStructuredSelection) isel;
+    if (issel.size() != 1)
+      return;
+    Object element = issel.getFirstElement();
+
+    if (element instanceof DFSFile) {
+      menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN, new DFSAction(
+          DFSActions.OPEN));
+
+    } else if (element instanceof DFSFolder) {
+      menu.appendToGroup(ICommonMenuConstants.GROUP_NEW, new DFSAction(
+          DFSActions.MKDIR));
+      menu.appendToGroup(ICommonMenuConstants.GROUP_NEW, new DFSAction(
+          DFSActions.UPLOAD_FILES));
+      menu.appendToGroup(ICommonMenuConstants.GROUP_NEW, new DFSAction(
+          DFSActions.UPLOAD_DIR));
+
+    } else if (element instanceof DFSLocation) {
+      menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN, new DFSAction(
+          DFSActions.RECONNECT));
+
+    } else if (element instanceof DFSLocationsRoot) {
+      menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN, new DFSAction(
+          DFSActions.DISCONNECT));
+    }
+
+  }
+
+  /**
+   * Representation of an action on a DFS entry in the browser
+   */
+  public static class DFSAction extends Action {
+
+    private final String id;
+
+    private final String title;
+
+    private DFSActions action;
+
+    public DFSAction(String id, String title) {
+      this.id = id;
+      this.title = title;
+    }
+
+    public DFSAction(DFSActions action) {
+      this.id = action.id;
+      this.title = action.title;
+    }
+
+    /* @inheritDoc */
+    @Override
+    public String getText() {
+      return this.title;
+    }
+
+    /* @inheritDoc */
+    @Override
+    public ImageDescriptor getImageDescriptor() {
+      return ImageLibrary.get(getActionDefinitionId());
+    }
+
+    /* @inheritDoc */
+    @Override
+    public String getActionDefinitionId() {
+      return id;
+    }
+
+    /* @inheritDoc */
+    @Override
+    public void run() {
+      DFSActionImpl action = new DFSActionImpl();
+      action.setActivePart(this, PlatformUI.getWorkbench()
+          .getActiveWorkbenchWindow().getActivePage().getActivePart());
+      action.selectionChanged(this, site.getStructuredViewer()
+          .getSelection());
+      action.run(this);
+    }
+
+    /* @inheritDoc */
+    @Override
+    public boolean isEnabled() {
+      return true;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSActions.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSActions.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSActions.java
new file mode 100644
index 0000000..038497a
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSActions.java
@@ -0,0 +1,44 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+public enum DFSActions {
+
+  DELETE("Delete"), REFRESH("Refresh"), DOWNLOAD("Download from DFS..."), OPEN(
+      "View"), MKDIR("Create new directory..."), UPLOAD_FILES(
+      "Upload files to DFS..."), UPLOAD_DIR("Upload directory to DFS..."), RECONNECT(
+      "Reconnect"), DISCONNECT("Disconnect");
+
+  final String title;
+
+  final String id;
+
+  private static final String PREFIX = "dfs.browser.action.";
+
+  public static DFSActions getById(String def) {
+    if (!def.startsWith(PREFIX))
+      return null;
+    return valueOf(def.substring(PREFIX.length()).toUpperCase());
+  }
+
+  DFSActions(String title) {
+    this.title = title;
+    this.id = PREFIX + this.name().toLowerCase();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContent.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContent.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContent.java
new file mode 100644
index 0000000..bea94d5
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContent.java
@@ -0,0 +1,32 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+/**
+ * Interface to define content entities in the DFS browser
+ */
+public interface DFSContent {
+
+  boolean hasChildren();
+  
+  DFSContent[] getChildren();
+  
+  void refresh();
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContentProvider.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContentProvider.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContentProvider.java
new file mode 100644
index 0000000..fca7d46
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSContentProvider.java
@@ -0,0 +1,244 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.eclipse.ImageLibrary;
+import org.apache.hadoop.eclipse.server.HadoopServer;
+import org.apache.hadoop.eclipse.servers.ServerRegistry;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Handles viewing of DFS locations
+ * <p>
+ * 
+ * The content handled by this provider is a tree:
+ * 
+ * <tt>
+ * <br>DFSLocationsRoot
+ * <br>\_HadoopServer
+ * <br>|  \_DfsFolder
+ * <br>|  |  \_DfsFile
+ * <br>|  \_DfsFolder
+ * <br>| ...
+ * <br>\_HadoopServer...
+ * </tt>
+ * 
+ * The code should not block here: blocking operations need to be done
+ * asynchronously so as not to freeze the UI!
+ */
+public class DFSContentProvider implements ITreeContentProvider,
+    ILabelProvider {
+
+  /**
+   * The viewer that displays this Tree content
+   */
+  private Viewer viewer;
+
+  private StructuredViewer sviewer;
+
+  private Map<HadoopServer, DFSContent> rootFolders =
+      new HashMap<HadoopServer, DFSContent>();
+
+  /**
+   * Constructor: load resources (icons).
+   */
+  public DFSContentProvider() {
+  }
+
+  private final DFSLocationsRoot locationsRoot = new DFSLocationsRoot(this);
+
+  /*
+   * ITreeContentProvider implementation
+   */
+
+  /* @inheritDoc */
+  public Object[] getChildren(Object parent) {
+
+    if (!(parent instanceof DFSContent))
+      return null;
+    DFSContent content = (DFSContent) parent;
+    return content.getChildren();
+  }
+
+  public Object[] test(Object parentElement) {
+    if (parentElement instanceof DFSLocationsRoot) {
+      return ServerRegistry.getInstance().getServers().toArray();
+
+    } else if (parentElement instanceof HadoopServer) {
+      final HadoopServer location = (HadoopServer) parentElement;
+      Object root = rootFolders.get(location);
+      if (root != null)
+        return new Object[] { root };
+
+      return new Object[] { "Connecting to DFS..." };
+
+    } else if (parentElement instanceof DFSFolder) {
+      DFSFolder folder = (DFSFolder) parentElement;
+      return folder.getChildren();
+    }
+
+    return new Object[] { "<Unknown DFSContent>" };
+  }
+
+  /* @inheritDoc */
+  public Object getParent(Object element) {
+
+    if (element instanceof DFSPath) {
+      return ((DFSPath) element).getParent();
+
+    } else if (element instanceof HadoopServer) {
+      return locationsRoot;
+    }
+
+    return null;
+  }
+
+  /* @inheritDoc */
+  public boolean hasChildren(Object element) {
+    if (element instanceof DFSContent) {
+      DFSContent content = (DFSContent) element;
+      return content.hasChildren();
+    }
+    return false;
+  }
+
+  /*
+   * IStructureContentProvider implementation
+   */
+
+  /* @inheritDoc */
+  public Object[] getElements(final Object inputElement) {
+    return new Object[] { locationsRoot };
+    // return ServerRegistry.getInstance().getServers().toArray();
+  }
+
+  /*
+   * ILabelProvider implementation
+   */
+
+  /* @inheritDoc */
+  public Image getImage(Object element) {
+    if (element instanceof DFSLocationsRoot)
+      return ImageLibrary.getImage("dfs.browser.root.entry");
+
+    else if (element instanceof DFSLocation)
+      return ImageLibrary.getImage("dfs.browser.location.entry");
+
+    else if (element instanceof DFSFolder)
+      return ImageLibrary.getImage("dfs.browser.folder.entry");
+
+    else if (element instanceof DFSFile)
+      return ImageLibrary.getImage("dfs.browser.file.entry");
+
+    return null;
+  }
+
+  /* @inheritDoc */
+  public String getText(Object element) {
+    if (element instanceof DFSFile)
+      return ((DFSFile) element).toDetailedString();
+
+    return element.toString();
+  }
+
+  /*
+   * IBaseLabelProvider implementation
+   */
+
+  /* @inheritDoc */
+  public void addListener(ILabelProviderListener listener) {
+  }
+
+  /* @inheritDoc */
+  public void removeListener(ILabelProviderListener listener) {
+  }
+
+  /* @inheritDoc */
+  public boolean isLabelProperty(Object element, String property) {
+    return false;
+  }
+
+  /*
+   * IContentProvider implementation
+   */
+
+  /* @inheritDoc */
+  public void dispose() {
+  }
+
+  /* @inheritDoc */
+  public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+    this.viewer = viewer;
+    if ((viewer != null) && (viewer instanceof StructuredViewer))
+      this.sviewer = (StructuredViewer) viewer;
+    else
+      this.sviewer = null;
+  }
+
+  /*
+   * Miscellaneous
+   */
+
+  /**
+   * Ask the viewer for this content to refresh
+   */
+  void refresh() {
+    // no display, nothing to update
+    if (this.viewer == null)
+      return;
+
+    Display.getDefault().asyncExec(new Runnable() {
+      public void run() {
+        DFSContentProvider.this.viewer.refresh();
+      }
+    });
+  }
+
+  /**
+   * Ask the viewer to refresh a single element
+   * 
+   * @param content what to refresh
+   */
+  void refresh(final DFSContent content) {
+    if (this.sviewer != null) {
+      Display.getDefault().asyncExec(new Runnable() {
+        public void run() {
+          DFSContentProvider.this.sviewer.refresh(content);
+        }
+      });
+
+    } else {
+      refresh();
+    }
+  }
+
+  Viewer getViewer() {
+    return this.viewer;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFile.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFile.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFile.java
new file mode 100644
index 0000000..af8e6c1
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFile.java
@@ -0,0 +1,350 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.hadoop.eclipse.Activator;
+import org.apache.hadoop.eclipse.ErrorMessageDialog;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * File handling methods for the DFS
+ */
+public class DFSFile extends DFSPath implements DFSContent {
+
+  protected long length;
+
+  protected short replication;
+
+  /**
+   * Constructor to upload a file on the distributed file system
+   * 
+   * @param parent
+   * @param path
+   * @param file
+   * @param monitor
+   */
+  public DFSFile(DFSPath parent, Path path, File file,
+      IProgressMonitor monitor) {
+
+    super(parent, path);
+    this.upload(monitor, file);
+  }
+
+  public DFSFile(DFSPath parent, Path path) {
+    super(parent, path);
+
+    try {
+      FileStatus fs = getDFS().getFileStatus(path);
+      this.length = fs.getLen();
+      this.replication = fs.getReplication();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * Download and view contents of a file
+   * 
+   * @return a InputStream for the file
+   */
+  public InputStream open() throws IOException {
+
+    return getDFS().open(this.path);
+  }
+
+  /**
+   * Download this file to the local file system. This creates a download
+   * status monitor.
+   * 
+   * @param file
+   * @throws JSchException
+   * @throws IOException
+   * @throws InvocationTargetException
+   * @throws InterruptedException
+   * 
+   * @deprecated
+   */
+  public void downloadToLocalFile(final File file)
+      throws InvocationTargetException, InterruptedException {
+
+    PlatformUI.getWorkbench().getProgressService().busyCursorWhile(
+        new IRunnableWithProgress() {
+          public void run(IProgressMonitor monitor)
+              throws InvocationTargetException {
+
+            DFSFile.this.downloadToLocalFile(monitor, file);
+          }
+        });
+  }
+
+  /* @inheritDoc */
+  @Override
+  public void downloadToLocalDirectory(IProgressMonitor monitor, File dir) {
+
+    File dfsPath = new File(this.getPath().toString());
+    File destination = new File(dir, dfsPath.getName());
+
+    if (destination.exists()) {
+      boolean answer =
+          MessageDialog.openQuestion(null, "Overwrite existing local file?",
+              "The file you are attempting to download from the DFS "
+                  + this.getPath()
+                  + ", already exists in your local directory as "
+                  + destination + ".\n" + "Overwrite the existing file?");
+      if (!answer)
+        return;
+    }
+
+    try {
+      this.downloadToLocalFile(monitor, destination);
+
+    } catch (Exception e) {
+      e.printStackTrace();
+      MessageDialog.openWarning(null, "Download to local file system",
+          "Downloading of file \"" + this.path + "\" to local directory \""
+              + dir + "\" has failed.\n" + e);
+    }
+  }
+
+  /**
+   * Provides a detailed string for this file
+   * 
+   * @return the string formatted as
+   *         <tt>&lt;filename&gt; (&lt;size&gt;, r&lt;replication&gt;)</tt>
+   */
+  public String toDetailedString() {
+    final String[] units = { "b", "Kb", "Mb", "Gb", "Tb" };
+    int unit = 0;
+    double l = this.length;
+    while ((l >= 1024.0) && (unit < units.length)) {
+      unit += 1;
+      l /= 1024.0;
+    }
+
+    return String.format("%s (%.1f %s, r%d)", super.toString(), l,
+        units[unit], this.replication);
+  }
+
+  /* @inheritDoc */
+  @Override
+  public String toString() {
+    return this.path.toString();
+  }
+
+  /*
+   * 
+   */
+
+  /**
+   * Download the DfsFile to a local file. Use the given monitor to report
+   * status of operation.
+   * 
+   * @param monitor the status monitor
+   * @param file the local file where to put the downloaded file
+   * @throws InvocationTargetException
+   */
+  public void downloadToLocalFile(IProgressMonitor monitor, File file)
+      throws InvocationTargetException {
+
+    final int taskSize = 1024;
+
+    monitor.setTaskName("Download file " + this.path);
+
+    BufferedOutputStream ostream = null;
+    DataInputStream istream = null;
+
+    try {
+      istream = getDFS().open(this.path);
+      ostream = new BufferedOutputStream(new FileOutputStream(file));
+
+      int bytes;
+      byte[] buffer = new byte[taskSize];
+
+      while ((bytes = istream.read(buffer)) >= 0) {
+        if (monitor.isCanceled())
+          return;
+        ostream.write(buffer, 0, bytes);
+        monitor.worked(1);
+      }
+
+    } catch (Exception e) {
+      throw new InvocationTargetException(e);
+
+    } finally {
+      // Clean all opened resources
+      if (istream != null) {
+        try {
+          istream.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+          // nothing we can do here
+        }
+      }
+      try {
+        ostream.close();
+      } catch (IOException e) {
+        e.printStackTrace();
+        // nothing we can do here
+      }
+    }
+  }
+
+  /**
+   * Upload a local file to this file on the distributed file system
+   * 
+   * @param monitor
+   * @param file
+   */
+  public void upload(IProgressMonitor monitor, File file) {
+
+    final int taskSize = 1024;
+
+    monitor.setTaskName("Upload file " + this.path);
+
+    BufferedInputStream istream = null;
+    DataOutputStream ostream = null;
+
+    try {
+      istream = new BufferedInputStream(new FileInputStream(file));
+      ostream = getDFS().create(this.path);
+
+      int bytes;
+      byte[] buffer = new byte[taskSize];
+
+      while ((bytes = istream.read(buffer)) >= 0) {
+        if (monitor.isCanceled())
+          return;
+        ostream.write(buffer, 0, bytes);
+        monitor.worked(1);
+      }
+
+    } catch (Exception e) {
+      ErrorMessageDialog.display(String.format(
+          "Unable to uploade file %s to %s", file, this.path), e
+          .getLocalizedMessage());
+
+    } finally {
+      try {
+        if (istream != null)
+          istream.close();
+      } catch (IOException e) {
+        e.printStackTrace();
+        // nothing we can do here
+      }
+      try {
+        if (ostream != null)
+          ostream.close();
+      } catch (IOException e) {
+        e.printStackTrace();
+        // nothing we can do here
+      }
+    }
+  }
+
+  /* @inheritDoc */
+  @Override
+  public void refresh() {
+    getParent().refresh();
+  }
+
+  /* @inheritDoc */
+  @Override
+  public int computeDownloadWork() {
+    return 1 + (int) (this.length / 1024);
+  }
+
+  /**
+   * Creates an adapter for the file to open it in the Editor
+   * 
+   * @return the IStorage
+   */
+  public IStorage getIStorage() {
+    return new IStorageAdapter();
+  }
+
+  /**
+   * IStorage adapter to open the file in the Editor
+   */
+  private class IStorageAdapter extends PlatformObject implements IStorage {
+
+    /* @inheritDoc */
+    public InputStream getContents() throws CoreException {
+      try {
+        return DFSFile.this.open();
+
+      } catch (IOException ioe) {
+        throw new CoreException(new Status(Status.ERROR,
+                Activator.PLUGIN_ID, 0, "Unable to open file \""
+                + DFSFile.this.path + "\"", ioe));
+      }
+    }
+
+    /* @inheritDoc */
+    public IPath getFullPath() {
+      return new org.eclipse.core.runtime.Path(DFSFile.this.path.toString());
+    }
+
+    /* @inheritDoc */
+    public String getName() {
+      return DFSFile.this.path.getName();
+    }
+
+    /* @inheritDoc */
+    public boolean isReadOnly() {
+      return true;
+    }
+
+  }
+
+  /*
+   * Implementation of DFSContent
+   */
+
+  /* @inheritDoc */
+  public DFSContent[] getChildren() {
+    return null;
+  }
+
+  /* @inheritDoc */
+  public boolean hasChildren() {
+    return false;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFolder.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFolder.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFolder.java
new file mode 100644
index 0000000..7dc72a7
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSFolder.java
@@ -0,0 +1,213 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.hadoop.eclipse.server.HadoopServer;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.Path;
+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.jface.dialogs.MessageDialog;
+
+/**
+ * Local representation of a folder in the DFS.
+ * 
+ * The constructor creates an empty representation of the folder and spawn a
+ * thread that will fill
+ */
+public class DFSFolder extends DFSPath implements DFSContent {
+
+  static Logger log = Logger.getLogger(DFSFolder.class.getName());
+
+  private DFSContent[] children;
+
+  protected DFSFolder(DFSContentProvider provider, HadoopServer location)
+      throws IOException {
+
+    super(provider, location);
+  }
+
+  private DFSFolder(DFSPath parent, Path path) {
+    super(parent, path);
+  }
+
+  protected void loadDFSFolderChildren() throws IOException {
+    List<DFSPath> list = new ArrayList<DFSPath>();
+
+    for (FileStatus status : getDFS().listStatus(this.getPath())) {
+      if (status.isDir()) {
+        list.add(new DFSFolder(this, status.getPath()));
+      } else {
+        list.add(new DFSFile(this, status.getPath()));
+      }
+    }
+
+    this.children = list.toArray(new DFSContent[list.size()]);
+  }
+
+  /**
+   * Upload the given file or directory into this DfsFolder
+   * 
+   * @param file
+   * @throws IOException
+   */
+  public void upload(IProgressMonitor monitor, final File file)
+      throws IOException {
+
+    if (file.isDirectory()) {
+      Path filePath = new Path(this.path, file.getName());
+      getDFS().mkdirs(filePath);
+      DFSFolder newFolder = new DFSFolder(this, filePath);
+      monitor.worked(1);
+      for (File child : file.listFiles()) {
+        if (monitor.isCanceled())
+          return;
+        newFolder.upload(monitor, child);
+      }
+
+    } else if (file.isFile()) {
+      Path filePath = new Path(this.path, file.getName());
+      DFSFile newFile = new DFSFile(this, filePath, file, monitor);
+
+    } else {
+      // XXX don't know what the file is?
+    }
+  }
+
+  /* @inheritDoc */
+  @Override
+  public void downloadToLocalDirectory(IProgressMonitor monitor, File dir) {
+    if (!dir.exists())
+      dir.mkdirs();
+
+    if (!dir.isDirectory()) {
+      MessageDialog.openError(null, "Download to local file system",
+          "Invalid directory location: \"" + dir + "\"");
+      return;
+    }
+
+    File dfsPath = new File(this.getPath().toString());
+    File destination = new File(dir, dfsPath.getName());
+
+    if (!destination.exists()) {
+      if (!destination.mkdir()) {
+        MessageDialog.openError(null, "Download to local directory",
+            "Unable to create directory " + destination.getAbsolutePath());
+        return;
+      }
+    }
+
+    // Download all DfsPath children
+    for (Object childObj : getChildren()) {
+      if (childObj instanceof DFSPath) {
+        ((DFSPath) childObj).downloadToLocalDirectory(monitor, destination);
+        monitor.worked(1);
+      }
+    }
+  }
+
+  /* @inheritDoc */
+  @Override
+  public int computeDownloadWork() {
+    int work = 1;
+    for (DFSContent child : getChildren()) {
+      if (child instanceof DFSPath)
+        work += ((DFSPath) child).computeDownloadWork();
+    }
+
+    return work;
+  }
+
+  /**
+   * Create a new sub directory into this directory
+   * 
+   * @param folderName
+   */
+  public void mkdir(String folderName) {
+    try {
+      getDFS().mkdirs(new Path(this.path, folderName));
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+    doRefresh();
+  }
+
+  /*
+   * Implementation of DFSContent
+   */
+
+  /* @inheritDoc */
+  public boolean hasChildren() {
+    if (this.children == null)
+      return true;
+    else
+      return (this.children.length > 0);
+  }
+
+  /* @inheritDoc */
+  public DFSContent[] getChildren() {
+    if (children == null) {
+      new Job("Connecting to DFS " + location) {
+        @Override
+        protected IStatus run(IProgressMonitor monitor) {
+          try {
+            loadDFSFolderChildren();
+            return Status.OK_STATUS;
+
+          } catch (IOException ioe) {
+            children =
+                new DFSContent[] { new DFSMessage("Error: "
+                    + ioe.getLocalizedMessage()) };
+            return Status.CANCEL_STATUS;
+
+          } finally {
+            // Under all circumstances, update the UI
+            provider.refresh(DFSFolder.this);
+          }
+        }
+      }.schedule();
+
+      return new DFSContent[] { new DFSMessage("Listing folder content...") };
+    }
+    return this.children;
+  }
+
+  /* @inheritDoc */
+  @Override
+  public void refresh() {
+    this.children = null;
+    this.doRefresh();
+  }
+
+  /* @inheritDoc */
+  @Override
+  public String toString() {
+    return String.format("%s (%s)", super.toString(),
+        this.getChildren().length);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocation.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocation.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocation.java
new file mode 100644
index 0000000..31c8fb3
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocation.java
@@ -0,0 +1,108 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+import java.io.IOException;
+
+import org.apache.hadoop.eclipse.server.HadoopServer;
+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;
+
+/**
+ * DFS Content representation of a HDFS location
+ */
+public class DFSLocation implements DFSContent {
+
+  private final DFSContentProvider provider;
+
+  private final HadoopServer location;
+
+  private DFSContent rootFolder = null;
+
+  DFSLocation(DFSContentProvider provider, HadoopServer server) {
+    this.provider = provider;
+    this.location = server;
+  }
+
+  /* @inheritDoc */
+  @Override
+  public String toString() {
+    return this.location.getLocationName();
+  }
+
+  /*
+   * Implementation of DFSContent
+   */
+
+  /* @inheritDoc */
+  public DFSContent[] getChildren() {
+    if (this.rootFolder == null) {
+      /*
+       * DfsFolder constructor might block as it contacts the NameNode: work
+       * asynchronously here or this will potentially freeze the UI
+       */
+      new Job("Connecting to DFS " + location) {
+        @Override
+        protected IStatus run(IProgressMonitor monitor) {
+          try {
+            rootFolder = new DFSFolder(provider, location);
+            return Status.OK_STATUS;
+
+          } catch (IOException ioe) {
+            rootFolder =
+                new DFSMessage("Error: " + ioe.getLocalizedMessage());
+            return Status.CANCEL_STATUS;
+
+          } finally {
+            // Under all circumstances, update the UI
+            provider.refresh(DFSLocation.this);
+          }
+        }
+      }.schedule();
+
+      return new DFSContent[] { new DFSMessage("Connecting to DFS "
+          + toString()) };
+    }
+    return new DFSContent[] { this.rootFolder };
+  }
+
+  /* @inheritDoc */
+  public boolean hasChildren() {
+    return true;
+  }
+  
+  /* @inheritDoc */
+  public void refresh() {
+    this.rootFolder = null;
+    this.provider.refresh(this);
+  }
+
+  /*
+   * Actions
+   */
+  
+  /**
+   * Refresh the location using a new connection
+   */
+  public void reconnect() {
+    this.refresh();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocationsRoot.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocationsRoot.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocationsRoot.java
new file mode 100644
index 0000000..9d9a609
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSLocationsRoot.java
@@ -0,0 +1,150 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.eclipse.server.HadoopServer;
+import org.apache.hadoop.eclipse.servers.IHadoopServerListener;
+import org.apache.hadoop.eclipse.servers.ServerRegistry;
+import org.apache.hadoop.fs.FileSystem;
+
+/**
+ * Representation of the root element containing all DFS servers. This
+ * content registers an observer on Hadoop servers so as to update itself
+ * when servers are updated.
+ */
+public class DFSLocationsRoot implements DFSContent, IHadoopServerListener {
+
+  /**
+   * 
+   */
+  private final DFSContentProvider provider;
+
+  private Map<HadoopServer, DFSLocation> map =
+      new HashMap<HadoopServer, DFSLocation>();
+
+  /**
+   * Register a listeners to track DFS locations updates
+   * 
+   * @param provider the content provider this content is the root of
+   */
+  DFSLocationsRoot(DFSContentProvider provider) {
+    this.provider = provider;
+    ServerRegistry.getInstance().addListener(this);
+    this.refresh();
+  }
+
+  /*
+   * Implementation of IHadoopServerListener
+   */
+
+  /* @inheritDoc */
+  public synchronized void serverChanged(final HadoopServer location,
+      final int type) {
+
+    switch (type) {
+      case ServerRegistry.SERVER_STATE_CHANGED: {
+        this.provider.refresh(map.get(location));
+        break;
+      }
+
+      case ServerRegistry.SERVER_ADDED: {
+        DFSLocation dfsLoc = new DFSLocation(provider, location);
+        map.put(location, dfsLoc);
+        this.provider.refresh(this);
+        break;
+      }
+
+      case ServerRegistry.SERVER_REMOVED: {
+        map.remove(location);
+        this.provider.refresh(this);
+        break;
+      }
+    }
+  }
+
+  /**
+   * Recompute the map of Hadoop locations
+   */
+  private synchronized void reloadLocations() {
+    map.clear();
+    for (HadoopServer location : ServerRegistry.getInstance().getServers())
+      map.put(location, new DFSLocation(provider, location));
+  }
+
+  /* @inheritDoc */
+  @Override
+  public String toString() {
+    return "DFS Locations";
+  }
+
+  /*
+   * Implementation of DFSContent
+   */
+
+  /* @inheritDoc */
+  public synchronized DFSContent[] getChildren() {
+    return this.map.values().toArray(new DFSContent[this.map.size()]);
+  }
+
+  /* @inheritDoc */
+  public boolean hasChildren() {
+    return (this.map.size() > 0);
+  }
+
+  /* @inheritDoc */
+  public void refresh() {
+    reloadLocations();
+    this.provider.refresh(this);
+  }
+
+  /*
+   * Actions
+   */
+
+  public void disconnect() {
+    Thread closeThread = new Thread() {
+      /* @inheritDoc */
+      @Override
+      public void run() {
+        try {
+          System.out.printf("Closing all opened File Systems...\n");
+          FileSystem.closeAll();
+          System.out.printf("File Systems closed\n");
+
+        } catch (IOException ioe) {
+          ioe.printStackTrace();
+        }
+      }
+    };
+
+    // Wait 5 seconds for the connections to be closed
+    closeThread.start();
+    try {
+      closeThread.join(5000);
+
+    } catch (InterruptedException ie) {
+      // Ignore
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSMessage.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSMessage.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSMessage.java
new file mode 100644
index 0000000..ce83b9a
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSMessage.java
@@ -0,0 +1,57 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+/**
+ * DFS Content that displays a message.
+ */
+class DFSMessage implements DFSContent {
+
+  private String message;
+
+  DFSMessage(String message) {
+    this.message = message;
+  }
+
+  /* @inheritDoc */
+  @Override
+  public String toString() {
+    return this.message;
+  }
+
+  /*
+   * Implementation of DFSContent
+   */
+
+  /* @inheritDoc */
+  public DFSContent[] getChildren() {
+    return null;
+  }
+
+  /* @inheritDoc */
+  public boolean hasChildren() {
+    return false;
+  }
+
+  /* @inheritDoc */
+  public void refresh() {
+    // Nothing to do
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSPath.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSPath.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSPath.java
new file mode 100644
index 0000000..0abd538
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/dfs/DFSPath.java
@@ -0,0 +1,160 @@
+/**
+ * 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 org.apache.hadoop.eclipse.dfs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import org.apache.hadoop.hdfs.DistributedFileSystem;
+import org.apache.hadoop.eclipse.ErrorMessageDialog;
+import org.apache.hadoop.eclipse.server.ConfProp;
+import org.apache.hadoop.eclipse.server.HadoopServer;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * DFS Path handling for DFS
+ */
+public abstract class DFSPath implements DFSContent {
+
+  protected final DFSContentProvider provider;
+
+  protected HadoopServer location;
+
+  private DistributedFileSystem dfs = null;
+
+  protected final Path path;
+
+  protected final DFSPath parent;
+
+  /**
+   * For debugging purpose
+   */
+  static Logger log = Logger.getLogger(DFSPath.class.getName());
+
+  /**
+   * Create a path representation for the given location in the given viewer
+   * 
+   * @param location
+   * @param path
+   * @param viewer
+   */
+  public DFSPath(DFSContentProvider provider, HadoopServer location)
+      throws IOException {
+
+    this.provider = provider;
+    this.location = location;
+    this.path = new Path("/");
+    this.parent = null;
+  }
+
+  /**
+   * Create a sub-path representation for the given parent path
+   * 
+   * @param parent
+   * @param path
+   */
+  protected DFSPath(DFSPath parent, Path path) {
+    this.provider = parent.provider;
+    this.location = parent.location;
+    this.dfs = parent.dfs;
+    this.parent = parent;
+    this.path = path;
+  }
+
+  protected void dispose() {
+    // Free the DFS connection
+  }
+
+  /* @inheritDoc */
+  @Override
+  public String toString() {
+    if (path.equals("/")) {
+      return location.getConfProp(ConfProp.FS_DEFAULT_URI);
+
+    } else {
+      return this.path.getName();
+    }
+  }
+
+  /**
+   * Does a recursive delete of the remote directory tree at this node.
+   */
+  public void delete() {
+    try {
+      getDFS().delete(this.path, true);
+
+    } catch (IOException e) {
+      e.printStackTrace();
+      MessageDialog.openWarning(null, "Delete file",
+          "Unable to delete file \"" + this.path + "\"\n" + e);
+    }
+  }
+
+  public DFSPath getParent() {
+    return parent;
+  }
+
+  public abstract void refresh();
+
+  /**
+   * Refresh the UI element for this content
+   */
+  public void doRefresh() {
+    provider.refresh(this);
+  }
+
+  /**
+   * Copy the DfsPath to the given local directory
+   * 
+   * @param directory the local directory
+   */
+  public abstract void downloadToLocalDirectory(IProgressMonitor monitor,
+      File dir);
+
+  public Path getPath() {
+    return this.path;
+  }
+
+  /**
+   * Gets a connection to the DFS
+   * 
+   * @return a connection to the DFS
+   * @throws IOException
+   */
+  DistributedFileSystem getDFS() throws IOException {
+    if (this.dfs == null) {
+      FileSystem fs = location.getDFS();
+      if (!(fs instanceof DistributedFileSystem)) {
+        ErrorMessageDialog.display("DFS Browser",
+            "The DFS Browser cannot browse anything else "
+                + "but a Distributed File System!");
+        throw new IOException("DFS Browser expects a DistributedFileSystem!");
+      }
+      this.dfs = (DistributedFileSystem) fs;
+    }
+    return this.dfs;
+  }
+
+  public abstract int computeDownloadWork();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/HadoopApplicationLaunchShortcut.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/HadoopApplicationLaunchShortcut.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/HadoopApplicationLaunchShortcut.java
new file mode 100644
index 0000000..1678e0d
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/HadoopApplicationLaunchShortcut.java
@@ -0,0 +1,145 @@
+/**
+ * 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 org.apache.hadoop.eclipse.launch;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.hadoop.eclipse.servers.RunOnHadoopWizard;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaApplicationLaunchShortcut;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Add a shortcut "Run on Hadoop" to the Run menu
+ */
+
+public class HadoopApplicationLaunchShortcut extends
+    JavaApplicationLaunchShortcut {
+
+  static Logger log =
+      Logger.getLogger(HadoopApplicationLaunchShortcut.class.getName());
+
+  // private ActionDelegate delegate = new RunOnHadoopActionDelegate();
+
+  public HadoopApplicationLaunchShortcut() {
+  }
+
+  /* @inheritDoc */
+  @Override
+  protected ILaunchConfiguration findLaunchConfiguration(IType type,
+      ILaunchConfigurationType configType) {
+
+    // Find an existing or create a launch configuration (Standard way)
+    ILaunchConfiguration iConf =
+        super.findLaunchConfiguration(type, configType);
+    if (iConf == null) iConf = super.createConfiguration(type);
+    ILaunchConfigurationWorkingCopy iConfWC;
+    try {
+      /*
+       * Tune the default launch configuration: setup run-time classpath
+       * manually
+       */
+      iConfWC = iConf.getWorkingCopy();
+
+      iConfWC.setAttribute(
+          IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
+
+      List<String> classPath = new ArrayList<String>();
+      IResource resource = type.getResource();
+      IJavaProject project =
+          (IJavaProject) resource.getProject().getNature(JavaCore.NATURE_ID);
+      IRuntimeClasspathEntry cpEntry =
+          JavaRuntime.newDefaultProjectClasspathEntry(project);
+      classPath.add(0, cpEntry.getMemento());
+
+      iConfWC.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH,
+          classPath);
+
+    } catch (CoreException e) {
+      e.printStackTrace();
+      // FIXME Error dialog
+      return null;
+    }
+
+    /*
+     * Update the selected configuration with a specific Hadoop location
+     * target
+     */
+    IResource resource = type.getResource();
+    if (!(resource instanceof IFile))
+      return null;
+    RunOnHadoopWizard wizard =
+        new RunOnHadoopWizard((IFile) resource, iConfWC);
+    WizardDialog dialog =
+        new WizardDialog(Display.getDefault().getActiveShell(), wizard);
+
+    dialog.create();
+    dialog.setBlockOnOpen(true);
+    if (dialog.open() != WizardDialog.OK)
+      return null;
+
+    try {
+      
+      // Only save if some configuration is different.
+      if(!iConfWC.contentsEqual(iConf))
+        iConfWC.doSave();
+
+    } catch (CoreException e) {
+      e.printStackTrace();
+      // FIXME Error dialog
+      return null;
+    }
+
+    return iConfWC;
+  }
+
+  /**
+   * Was used to run the RunOnHadoopWizard inside and provide it a
+   * ProgressMonitor
+   */
+  static class Dialog extends WizardDialog {
+    public Dialog(Shell parentShell, IWizard newWizard) {
+      super(parentShell, newWizard);
+    }
+
+    @Override
+    public void create() {
+      super.create();
+
+      ((RunOnHadoopWizard) getWizard())
+          .setProgressMonitor(getProgressMonitor());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/LocalMapReduceLaunchTabGroup.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/LocalMapReduceLaunchTabGroup.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/LocalMapReduceLaunchTabGroup.java
new file mode 100644
index 0000000..66db5d2
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/LocalMapReduceLaunchTabGroup.java
@@ -0,0 +1,182 @@
+/**
+ * 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 org.apache.hadoop.eclipse.launch;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaJRETab;
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+/**
+ * 
+ * Handler for Local MapReduce job launches
+ * 
+ * TODO(jz) this may not be needed as we almost always deploy to a remote server
+ * and not locally, where we do do it locally we may just be able to exec
+ * scripts without going to java
+ * 
+ */
+public class LocalMapReduceLaunchTabGroup extends
+    AbstractLaunchConfigurationTabGroup {
+
+  public LocalMapReduceLaunchTabGroup() {
+    // TODO Auto-generated constructor stub
+  }
+
+  public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+    setTabs(new ILaunchConfigurationTab[] { new MapReduceLaunchTab(),
+        new JavaArgumentsTab(), new JavaJRETab(), new JavaClasspathTab(),
+        new CommonTab() });
+  }
+
+  public static class MapReduceLaunchTab extends AbstractLaunchConfigurationTab {
+    private Text combinerClass;
+
+    private Text reducerClass;
+
+    private Text mapperClass;
+
+    @Override
+    public boolean canSave() {
+      return true;
+    }
+
+    @Override
+    public boolean isValid(ILaunchConfiguration launchConfig) {
+      // todo: only if all classes are of proper types
+      return true;
+    }
+
+    public void createControl(final Composite parent) {
+      Composite panel = new Composite(parent, SWT.NONE);
+      GridLayout layout = new GridLayout(3, false);
+      panel.setLayout(layout);
+
+      Label mapperLabel = new Label(panel, SWT.NONE);
+      mapperLabel.setText("Mapper");
+      mapperClass = new Text(panel, SWT.SINGLE | SWT.BORDER);
+      createRow(parent, panel, mapperClass);
+
+      Label reducerLabel = new Label(panel, SWT.NONE);
+      reducerLabel.setText("Reducer");
+      reducerClass = new Text(panel, SWT.SINGLE | SWT.BORDER);
+      createRow(parent, panel, reducerClass);
+
+      Label combinerLabel = new Label(panel, SWT.NONE);
+      combinerLabel.setText("Combiner");
+      combinerClass = new Text(panel, SWT.SINGLE | SWT.BORDER);
+      createRow(parent, panel, combinerClass);
+
+      panel.pack();
+      setControl(panel);
+    }
+
+    private void createRow(final Composite parent, Composite panel,
+        final Text text) {
+      text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+      Button button = new Button(panel, SWT.BORDER);
+      button.setText("Browse...");
+      button.addListener(SWT.Selection, new Listener() {
+        public void handleEvent(Event arg0) {
+          try {
+            AST ast = AST.newAST(3);
+
+            SelectionDialog dialog = JavaUI.createTypeDialog(parent.getShell(),
+                new ProgressMonitorDialog(parent.getShell()), SearchEngine
+                    .createWorkspaceScope(),
+                IJavaElementSearchConstants.CONSIDER_CLASSES, false);
+            dialog.setMessage("Select Mapper type (implementing )");
+            dialog.setBlockOnOpen(true);
+            dialog.setTitle("Select Mapper Type");
+            dialog.open();
+
+            if ((dialog.getReturnCode() == Window.OK)
+                && (dialog.getResult().length > 0)) {
+              IType type = (IType) dialog.getResult()[0];
+              text.setText(type.getFullyQualifiedName());
+              setDirty(true);
+            }
+          } catch (JavaModelException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+          }
+        }
+      });
+    }
+
+    public String getName() {
+      return "Hadoop";
+    }
+
+    public void initializeFrom(ILaunchConfiguration configuration) {
+      try {
+        mapperClass.setText(configuration.getAttribute(
+            "org.apache.hadoop.eclipse.launch.mapper", ""));
+        reducerClass.setText(configuration.getAttribute(
+            "org.apache.hadoop.eclipse.launch.reducer", ""));
+        combinerClass.setText(configuration.getAttribute(
+            "org.apache.hadoop.eclipse.launch.combiner", ""));
+      } catch (CoreException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+        setErrorMessage(e.getMessage());
+      }
+    }
+
+    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+      configuration.setAttribute("org.apache.hadoop.eclipse.launch.mapper",
+          mapperClass.getText());
+      configuration.setAttribute(
+          "org.apache.hadoop.eclipse.launch.reducer", reducerClass
+              .getText());
+      configuration.setAttribute(
+          "org.apache.hadoop.eclipse.launch.combiner", combinerClass
+              .getText());
+    }
+
+    public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/MutexRule.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/MutexRule.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/MutexRule.java
new file mode 100644
index 0000000..46df449
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/MutexRule.java
@@ -0,0 +1,37 @@
+/**
+ * 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 org.apache.hadoop.eclipse.launch;
+
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+public class MutexRule implements ISchedulingRule {
+  private final String id;
+
+  public MutexRule(String id) {
+    this.id = id;
+  }
+
+  public boolean contains(ISchedulingRule rule) {
+    return (rule instanceof MutexRule) && ((MutexRule) rule).id.equals(id);
+  }
+
+  public boolean isConflicting(ISchedulingRule rule) {
+    return (rule instanceof MutexRule) && ((MutexRule) rule).id.equals(id);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/StartHadoopLaunchTabGroup.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/StartHadoopLaunchTabGroup.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/StartHadoopLaunchTabGroup.java
new file mode 100644
index 0000000..047ba17
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/launch/StartHadoopLaunchTabGroup.java
@@ -0,0 +1,47 @@
+/**
+ * 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 org.apache.hadoop.eclipse.launch;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaJRETab;
+
+/**
+ * Create the tab group for the dialog window for starting a Hadoop job.
+ */
+
+public class StartHadoopLaunchTabGroup extends
+    AbstractLaunchConfigurationTabGroup {
+
+  public StartHadoopLaunchTabGroup() {
+    // TODO Auto-generated constructor stub
+  }
+
+  /**
+   * TODO(jz) consider the appropriate tabs for this case
+   */
+  public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+    setTabs(new ILaunchConfigurationTab[] { new JavaArgumentsTab(),
+        new JavaJRETab(), new JavaClasspathTab(), new CommonTab() });
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/MapReducePreferencePage.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/MapReducePreferencePage.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/MapReducePreferencePage.java
new file mode 100644
index 0000000..cef50a3
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/MapReducePreferencePage.java
@@ -0,0 +1,64 @@
+/**
+ * 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 org.apache.hadoop.eclipse.preferences;
+
+import org.apache.hadoop.eclipse.Activator;
+import org.eclipse.jface.preference.DirectoryFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * This class represents a preference page that is contributed to the
+ * Preferences dialog. By sub-classing <tt>FieldEditorPreferencePage</tt>,
+ * we can use the field support built into JFace that allows us to create a
+ * page that is small and knows how to save, restore and apply itself.
+ * 
+ * <p>
+ * This page is used to modify preferences only. They are stored in the
+ * preference store that belongs to the main plug-in class. That way,
+ * preferences can be accessed directly via the preference store.
+ */
+
+public class MapReducePreferencePage extends FieldEditorPreferencePage
+    implements IWorkbenchPreferencePage {
+
+  public MapReducePreferencePage() {
+    super(GRID);
+    setPreferenceStore(Activator.getDefault().getPreferenceStore());
+    setTitle("Hadoop Map/Reduce Tools");
+    // setDescription("Hadoop Map/Reduce Preferences");
+  }
+
+  /**
+   * Creates the field editors. Field editors are abstractions of the common
+   * GUI blocks needed to manipulate various types of preferences. Each field
+   * editor knows how to save and restore itself.
+   */
+  @Override
+  public void createFieldEditors() {
+    addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH,
+        "&Hadoop installation directory:", getFieldEditorParent()));
+
+  }
+
+  /* @inheritDoc */
+  public void init(IWorkbench workbench) {
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceConstants.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceConstants.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceConstants.java
new file mode 100644
index 0000000..74641bb
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceConstants.java
@@ -0,0 +1,34 @@
+/**
+ * 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 org.apache.hadoop.eclipse.preferences;
+
+/**
+ * Constant definitions for plug-in preferences
+ */
+public class PreferenceConstants {
+
+  public static final String P_PATH = "pathPreference";
+
+  // public static final String P_BOOLEAN = "booleanPreference";
+  //
+  // public static final String P_CHOICE = "choicePreference";
+  //
+  // public static final String P_STRING = "stringPreference";
+  //	
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceInitializer.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceInitializer.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..444050a
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/preferences/PreferenceInitializer.java
@@ -0,0 +1,33 @@
+/**
+ * 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 org.apache.hadoop.eclipse.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+  /* @inheritDoc */
+  @Override
+  public void initializeDefaultPreferences() {
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/ConfProp.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/ConfProp.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/ConfProp.java
new file mode 100644
index 0000000..efc441b
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/ConfProp.java
@@ -0,0 +1,147 @@
+/**
+ * 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 org.apache.hadoop.eclipse.server;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+
+public enum ConfProp {
+  /**
+   * Property name for the Hadoop location name
+   */
+  PI_LOCATION_NAME(true, "location.name", "New Hadoop location"),
+
+  /**
+   * Property name for the master host name (the Job tracker)
+   */
+  PI_JOB_TRACKER_HOST(true, "jobtracker.host", "localhost"),
+
+  /**
+   * Property name for the DFS master host name (the Name node)
+   */
+  PI_NAME_NODE_HOST(true, "namenode.host", "localhost"),
+
+  /**
+   * Property name for the installation directory on the master node
+   */
+  // PI_INSTALL_DIR(true, "install.dir", "/dir/hadoop-version/"),
+  /**
+   * User name to use for Hadoop operations
+   */
+  PI_USER_NAME(true, "user.name", System.getProperty("user.name",
+      "who are you?")),
+
+  /**
+   * Property name for SOCKS proxy activation
+   */
+  PI_SOCKS_PROXY_ENABLE(true, "socks.proxy.enable", "no"),
+
+  /**
+   * Property name for the SOCKS proxy host
+   */
+  PI_SOCKS_PROXY_HOST(true, "socks.proxy.host", "host"),
+
+  /**
+   * Property name for the SOCKS proxy port
+   */
+  PI_SOCKS_PROXY_PORT(true, "socks.proxy.port", "1080"),
+
+  /**
+   * TCP port number for the name node
+   */
+  PI_NAME_NODE_PORT(true, "namenode.port", "50040"),
+
+  /**
+   * TCP port number for the job tracker
+   */
+  PI_JOB_TRACKER_PORT(true, "jobtracker.port", "50020"),
+
+  /**
+   * Are the Map/Reduce and the Distributed FS masters hosted on the same
+   * machine?
+   */
+  PI_COLOCATE_MASTERS(true, "masters.colocate", "yes"),
+
+  /**
+   * Property name for naming the job tracker (URI). This property is related
+   * to {@link #PI_MASTER_HOST_NAME}
+   */
+  JOB_TRACKER_URI(false, "mapreduce.jobtracker.address", "localhost:50020"),
+
+  /**
+   * Property name for naming the default file system (URI).
+   */
+  FS_DEFAULT_URI(false, "fs.default.name", "hdfs://localhost:50040/"),
+
+  /**
+   * Property name for the default socket factory:
+   */
+  SOCKET_FACTORY_DEFAULT(false, "hadoop.rpc.socket.factory.class.default",
+      "org.apache.hadoop.net.StandardSocketFactory"),
+
+  /**
+   * Property name for the SOCKS server URI.
+   */
+  SOCKS_SERVER(false, "hadoop.socks.server", "host:1080"),
+
+  ;
+
+  /**
+   * Map <property name> -> ConfProp
+   */
+  private static Map<String, ConfProp> map;
+
+  private static synchronized void registerProperty(String name,
+      ConfProp prop) {
+
+    if (ConfProp.map == null)
+      ConfProp.map = new HashMap<String, ConfProp>();
+
+    ConfProp.map.put(name, prop);
+  }
+
+  public static ConfProp getByName(String propName) {
+    return map.get(propName);
+  }
+
+  public final String name;
+
+  public final String defVal;
+
+  ConfProp(boolean internal, String name, String defVal) {
+    if (internal)
+      name = "eclipse.plug-in." + name;
+    this.name = name;
+    this.defVal = defVal;
+
+    ConfProp.registerProperty(name, this);
+  }
+
+  String get(Configuration conf) {
+    return conf.get(name);
+  }
+
+  void set(Configuration conf, String value) {
+    assert value != null;
+    conf.set(name, value);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopJob.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopJob.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopJob.java
new file mode 100644
index 0000000..c24253e
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopJob.java
@@ -0,0 +1,349 @@
+/**
+ * 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 org.apache.hadoop.eclipse.server;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.mapred.Counters;
+import org.apache.hadoop.mapred.JobConf;
+import org.apache.hadoop.mapred.JobID;
+import org.apache.hadoop.mapred.JobStatus;
+import org.apache.hadoop.mapred.RunningJob;
+
+/**
+ * Representation of a Map/Reduce running job on a given location
+ */
+
+public class HadoopJob {
+
+  /**
+   * Enum representation of a Job state
+   */
+  public enum JobState {
+    PREPARE(JobStatus.PREP), RUNNING(JobStatus.RUNNING), FAILED(
+        JobStatus.FAILED), SUCCEEDED(JobStatus.SUCCEEDED);
+
+    final int state;
+
+    JobState(int state) {
+      this.state = state;
+    }
+
+    static JobState ofInt(int state) {
+      if (state == JobStatus.PREP) {
+        return PREPARE;
+      }
+      else if (state == JobStatus.RUNNING) {
+        return RUNNING;
+      }
+      else if (state == JobStatus.FAILED) {
+        return FAILED;
+      }
+      else if (state == JobStatus.SUCCEEDED) {
+        return SUCCEEDED;
+      }
+      else {
+        return null;
+      }
+    }
+  }
+
+  /**
+   * Location this Job runs on
+   */
+  private final HadoopServer location;
+
+  /**
+   * Unique identifier of this Job
+   */
+  final JobID jobId;
+
+  /**
+   * Status representation of a running job. This actually contains a
+   * reference to a JobClient. Its methods might block.
+   */
+  RunningJob running;
+
+  /**
+   * Last polled status
+   * 
+   * @deprecated should apparently not be used
+   */
+  JobStatus status;
+
+  /**
+   * Last polled counters
+   */
+  Counters counters;
+
+  /**
+   * Job Configuration
+   */
+  JobConf jobConf = null;
+
+  boolean completed = false;
+
+  boolean successful = false;
+
+  boolean killed = false;
+
+  int totalMaps;
+
+  int totalReduces;
+
+  int completedMaps;
+
+  int completedReduces;
+
+  float mapProgress;
+
+  float reduceProgress;
+
+  /**
+   * Constructor for a Hadoop job representation
+   * 
+   * @param location
+   * @param id
+   * @param running
+   * @param status
+   */
+  public HadoopJob(HadoopServer location, JobID id, RunningJob running,
+      JobStatus status) {
+
+    this.location = location;
+    this.jobId = id;
+    this.running = running;
+
+    loadJobFile();
+
+    update(status);
+  }
+
+  /**
+   * Try to locate and load the JobConf file for this job so to get more
+   * details on the job (number of maps and of reduces)
+   */
+  private void loadJobFile() {
+    try {
+      String jobFile = getJobFile();
+      FileSystem fs = location.getDFS();
+      File tmp = File.createTempFile(getJobID().toString(), ".xml");
+      if (FileUtil.copy(fs, new Path(jobFile), tmp, false, location
+          .getConfiguration())) {
+        this.jobConf = new JobConf(tmp.toString());
+
+        this.totalMaps = jobConf.getNumMapTasks();
+        this.totalReduces = jobConf.getNumReduceTasks();
+      }
+
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+  }
+
+  /* @inheritDoc */
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((jobId == null) ? 0 : jobId.hashCode());
+    result = prime * result + ((location == null) ? 0 : location.hashCode());
+    return result;
+  }
+
+  /* @inheritDoc */
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj)
+      return true;
+    if (obj == null)
+      return false;
+    if (!(obj instanceof HadoopJob))
+      return false;
+    final HadoopJob other = (HadoopJob) obj;
+    if (jobId == null) {
+      if (other.jobId != null)
+        return false;
+    } else if (!jobId.equals(other.jobId))
+      return false;
+    if (location == null) {
+      if (other.location != null)
+        return false;
+    } else if (!location.equals(other.location))
+      return false;
+    return true;
+  }
+
+  /**
+   * Get the running status of the Job (@see {@link JobStatus}).
+   * 
+   * @return
+   */
+  public JobState getState() {
+    if (this.completed) {
+      if (this.successful) {
+        return JobState.SUCCEEDED;
+      } else {
+        return JobState.FAILED;
+      }
+    } else {
+      return JobState.RUNNING;
+    }
+    // return JobState.ofInt(this.status.getRunState());
+  }
+
+  /**
+   * @return
+   */
+  public JobID getJobID() {
+    return this.jobId;
+  }
+
+  /**
+   * @return
+   */
+  public HadoopServer getLocation() {
+    return this.location;
+  }
+
+  /**
+   * @return
+   */
+  public boolean isCompleted() {
+    return this.completed;
+  }
+
+  /**
+   * @return
+   */
+  public String getJobName() {
+    return this.running.getJobName();
+  }
+
+  /**
+   * @return
+   */
+  public String getJobFile() {
+    return this.running.getJobFile();
+  }
+
+  /**
+   * Return the tracking URL for this Job.
+   * 
+   * @return string representation of the tracking URL for this Job
+   */
+  public String getTrackingURL() {
+    return this.running.getTrackingURL();
+  }
+
+  /**
+   * Returns a string representation of this job status
+   * 
+   * @return string representation of this job status
+   */
+  public String getStatus() {
+
+    StringBuffer s = new StringBuffer();
+
+    s.append("Maps : " + completedMaps + "/" + totalMaps);
+    s.append(" (" + mapProgress + ")");
+    s.append("  Reduces : " + completedReduces + "/" + totalReduces);
+    s.append(" (" + reduceProgress + ")");
+
+    return s.toString();
+  }
+
+  /**
+   * Update this job status according to the given JobStatus
+   * 
+   * @param status
+   */
+  void update(JobStatus status) {
+    this.status = status;
+    try {
+      this.counters = running.getCounters();
+      this.completed = running.isComplete();
+      this.successful = running.isSuccessful();
+      this.mapProgress = running.mapProgress();
+      this.reduceProgress = running.reduceProgress();
+      // running.getTaskCompletionEvents(fromEvent);
+
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    }
+
+    this.completedMaps = (int) (this.totalMaps * this.mapProgress);
+    this.completedReduces = (int) (this.totalReduces * this.reduceProgress);
+  }
+
+  /**
+   * Print this job counters (for debugging purpose)
+   */
+  void printCounters() {
+    System.out.printf("New Job:\n", counters);
+    for (String groupName : counters.getGroupNames()) {
+      Counters.Group group = counters.getGroup(groupName);
+      System.out.printf("\t%s[%s]\n", groupName, group.getDisplayName());
+
+      for (Counters.Counter counter : group) {
+        System.out.printf("\t\t%s: %s\n", counter.getDisplayName(),
+                                          counter.getCounter());
+      }
+    }
+    System.out.printf("\n");
+  }
+
+  /**
+   * Kill this job
+   */
+  public void kill() {
+    try {
+      this.running.killJob();
+      this.killed = true;
+
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * Print this job status (for debugging purpose)
+   */
+  public void display() {
+    System.out.printf("Job id=%s, name=%s\n", getJobID(), getJobName());
+    System.out.printf("Configuration file: %s\n", getJobID());
+    System.out.printf("Tracking URL: %s\n", getTrackingURL());
+
+    System.out.printf("Completion: map: %f reduce %f\n",
+        100.0 * this.mapProgress, 100.0 * this.reduceProgress);
+
+    System.out.println("Job total maps = " + totalMaps);
+    System.out.println("Job completed maps = " + completedMaps);
+    System.out.println("Map percentage complete = " + mapProgress);
+    System.out.println("Job total reduces = " + totalReduces);
+    System.out.println("Job completed reduces = " + completedReduces);
+    System.out.println("Reduce percentage complete = " + reduceProgress);
+    System.out.flush();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hdt/blob/a1719e04/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopPathPage.java
----------------------------------------------------------------------
diff --git a/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopPathPage.java b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopPathPage.java
new file mode 100644
index 0000000..cf58b9c
--- /dev/null
+++ b/eclipse-plugin/src/java/org/apache/hadoop/eclipse/server/HadoopPathPage.java
@@ -0,0 +1,124 @@
+/**
+ * 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 org.apache.hadoop.eclipse.server;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PartInitException;
+
+public class HadoopPathPage implements IEditorPart {
+
+  public IEditorInput getEditorInput() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public IEditorSite getEditorSite() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public void init(IEditorSite site, IEditorInput input)
+      throws PartInitException {
+    // TODO Auto-generated method stub
+
+  }
+
+  public void addPropertyListener(IPropertyListener listener) {
+    // TODO Auto-generated method stub
+
+  }
+
+  public void createPartControl(Composite parent) {
+    // TODO Auto-generated method stub
+
+  }
+
+  public void dispose() {
+    // TODO Auto-generated method stub
+
+  }
+
+  public IWorkbenchPartSite getSite() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public String getTitle() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public Image getTitleImage() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public String getTitleToolTip() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public void removePropertyListener(IPropertyListener listener) {
+    // TODO Auto-generated method stub
+
+  }
+
+  public void setFocus() {
+    // TODO Auto-generated method stub
+
+  }
+
+  public Object getAdapter(Class adapter) {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public void doSave(IProgressMonitor monitor) {
+    // TODO Auto-generated method stub
+
+  }
+
+  public void doSaveAs() {
+    // TODO Auto-generated method stub
+
+  }
+
+  public boolean isDirty() {
+    // TODO Auto-generated method stub
+    return false;
+  }
+
+  public boolean isSaveAsAllowed() {
+    // TODO Auto-generated method stub
+    return false;
+  }
+
+  public boolean isSaveOnCloseNeeded() {
+    // TODO Auto-generated method stub
+    return false;
+  }
+
+}