hama-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From edwardy...@apache.org
Subject svn commit: r1610643 - in /hama/trunk: ./ core/src/main/java/org/apache/hama/http/ core/src/main/java/org/apache/hama/manager/ core/src/main/java/org/apache/hama/manager/util/ core/src/main/java/org/apache/hama/util/ core/src/main/resources/webapp/bspm...
Date Tue, 15 Jul 2014 10:59:26 GMT
Author: edwardyoon
Date: Tue Jul 15 10:59:25 2014
New Revision: 1610643

URL: http://svn.apache.org/r1610643
Log:
HAMA-910: Web UI Improvement (Victor Lee via edwardyoon)

Added:
    hama/trunk/core/src/main/java/org/apache/hama/manager/
    hama/trunk/core/src/main/java/org/apache/hama/manager/LogView.java   (with props)
    hama/trunk/core/src/main/java/org/apache/hama/manager/util/
    hama/trunk/core/src/main/java/org/apache/hama/manager/util/UITemplate.java   (with props)
    hama/trunk/core/src/main/resources/webapp/commons/
    hama/trunk/core/src/main/resources/webapp/commons/tpl/
    hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.configlist.html   (with props)
    hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.logview.html   (with props)
    hama/trunk/core/src/main/resources/webapp/static/
    hama/trunk/core/src/main/resources/webapp/static/hama.css   (with props)
    hama/trunk/core/src/test/java/org/apache/hama/manager/
    hama/trunk/core/src/test/java/org/apache/hama/manager/TestLogView.java   (with props)
    hama/trunk/core/src/test/java/org/apache/hama/manager/util/
    hama/trunk/core/src/test/java/org/apache/hama/manager/util/TestUITemplate.java   (with props)
Modified:
    hama/trunk/CHANGES.txt
    hama/trunk/core/src/main/java/org/apache/hama/http/HttpServer.java
    hama/trunk/core/src/main/java/org/apache/hama/util/BSPServletUtil.java
    hama/trunk/core/src/main/resources/webapp/bspmaster/bspjob.jsp
    hama/trunk/core/src/main/resources/webapp/bspmaster/bspmaster.jsp
    hama/trunk/core/src/main/resources/webapp/bspmaster/index.html
    hama/trunk/core/src/main/resources/webapp/bspmaster/machines.jsp
    hama/trunk/core/src/main/resources/webapp/groomserver/groomserver.jsp

Modified: hama/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hama/trunk/CHANGES.txt?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/CHANGES.txt (original)
+++ hama/trunk/CHANGES.txt Tue Jul 15 10:59:25 2014
@@ -17,6 +17,7 @@ Release 0.7.0 (unreleased changes)
 
   IMPROVEMENTS
 
+   HAMA-910: Web UI Improvement (Victor Lee via edwardyoon)
    HAMA-909: Improve Mesos Scheduler's Fault Tolerance (Jeff Fenchel via edwardyoon)
    HAMA-823: Remove javadoc warnings (Victor Lee via edwardyoon)  
    HAMA-886: Refactoring core.bundle package (edwardyoon)

Modified: hama/trunk/core/src/main/java/org/apache/hama/http/HttpServer.java
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/java/org/apache/hama/http/HttpServer.java?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/core/src/main/java/org/apache/hama/http/HttpServer.java (original)
+++ hama/trunk/core/src/main/java/org/apache/hama/http/HttpServer.java Tue Jul 15 10:59:25 2014
@@ -38,6 +38,7 @@ import org.apache.hadoop.conf.Configurat
 import org.apache.hadoop.log.LogLevel;
 import org.apache.hadoop.util.ReflectionUtils;
 import org.apache.hama.bsp.BSPMaster;
+import org.apache.hama.manager.LogView;
 import org.mortbay.jetty.Connector;
 import org.mortbay.jetty.Handler;
 import org.mortbay.jetty.Server;
@@ -65,7 +66,8 @@ public class HttpServer {
   public static final Log LOG = LogFactory.getLog(HttpServer.class);
 
   static final String FILTER_INITIALIZER_PROPERTY = "hama.http.filter.initializers";
-
+  public static final String CONF_CONTEXT_ATTRIBUTE = "hama.conf";
+  
   protected final Server webServer;
   protected final Connector listener;
   protected final WebAppContext webAppContext;
@@ -117,6 +119,7 @@ public class HttpServer {
       warPath = warPath + "/";
     }
     webAppContext.setWar(warPath);
+    webAppContext.getServletContext().setAttribute(CONF_CONTEXT_ATTRIBUTE, conf);    
     webServer.addHandler(webAppContext);
 
     addDefaultApps(contexts, appDir);
@@ -158,6 +161,11 @@ public class HttpServer {
     staticContext.setResourceBase(appDir + "/static");
     staticContext.addServlet(DefaultServlet.class, "/*");
     defaultContexts.put(staticContext, true);
+    // set up the context for "/commons/*"
+    Context commonsContext = new Context(parent, "/commons");
+    commonsContext.setResourceBase(appDir + "/commons");
+    commonsContext.addServlet(DefaultServlet.class, "/*");
+    defaultContexts.put(commonsContext, true);    
   }
 
   /**
@@ -166,7 +174,8 @@ public class HttpServer {
   protected void addDefaultServlets() {
     // set up default servlets
     addServlet("stacks", "/stacks", StackServlet.class);
-    addServlet("logLevel", "/logLevel", LogLevel.Servlet.class);
+    addServlet("logLevel", "/logLevel", LogLevel.Servlet.class);   
+    addServlet("logView", "/logView", LogView.Servlet.class);    
   }
 
   public void addContext(Context ctxt, boolean isFiltered) throws IOException {

Added: hama/trunk/core/src/main/java/org/apache/hama/manager/LogView.java
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/java/org/apache/hama/manager/LogView.java?rev=1610643&view=auto
==============================================================================
--- hama/trunk/core/src/main/java/org/apache/hama/manager/LogView.java (added)
+++ hama/trunk/core/src/main/java/org/apache/hama/manager/LogView.java Tue Jul 15 10:59:25 2014
@@ -0,0 +1,379 @@
+/**
+ * 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.hama.manager;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.SocketException;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hama.manager.util.UITemplate;
+
+public class LogView {
+
+  /**
+   * get log file list
+   * 
+   * @param directoryName directory Name
+   */
+  public static List<File> getLogFileList(String directoryName) {
+
+    List<File> list = new ArrayList<File>();
+    File dir = new File(directoryName);
+
+    if (dir.isDirectory()) {
+
+      File[] files = dir.listFiles();
+
+      Arrays.sort(files, new Comparator<File>() {
+        @Override
+        public int compare(File file1, File file2) {
+          return Long.compare(file2.lastModified(), file1.lastModified());
+        }
+      });
+
+      for (int i = 0; i < files.length; i++) {
+        list.add(files[i]);
+
+      }
+    }
+
+    return list;
+  }
+
+  /**
+   * Returns by changing to a string that is easy to read bytes, KB, MB, GB, TB,
+   * etc. of the filesize type size.
+   * 
+   * @param filesize Change filesize.
+   * @return The modified string
+   * @see DecimalFormat
+   */
+  public static String convertFileSize(long filesize) {
+    double size = filesize;
+    String unit = "bytes";
+    String format = "#,###.## ";
+
+    if (1048576 > filesize && filesize >= 1024) {
+      size = size / 1024;
+      unit = "KB";
+    } else if (1073741824 > filesize && filesize >= 1048576) {
+      size = size / 1048576;
+      unit = "MB";
+    } else if (1099511627776L > filesize && filesize >= 1073741824) {
+      size = size / 1073741824;
+      unit = "GB";
+    } else if (filesize >= 1099511627776L) {
+      size = size / 1099511627776L;
+      unit = "TB";
+    }
+
+    return new DecimalFormat(format).format(size) + unit;
+  }
+
+  /**
+   * download log file.
+   * 
+   * @param filPath log file path.
+   * @throws Exception
+   */
+  public static void downloadFile(HttpServletResponse response, String filePath)
+      throws ServletException, IOException {
+
+    File file = new File(filePath);
+
+    if (!file.exists()) {
+      throw new ServletException("File doesn't exists.");
+    }
+
+    String headerKey = "Content-Disposition";
+    String headerValue = "attachment; filename=\"" + file.getName() + "\"";
+
+    BufferedInputStream in = null;
+    BufferedOutputStream out = null;
+
+    try {
+
+      response.setContentType("application/octet-stream");
+      response.setContentLength((int) file.length());
+      response.setHeader(headerKey, headerValue);
+
+      in = new BufferedInputStream(new FileInputStream(file));
+      out = new BufferedOutputStream(response.getOutputStream());
+
+      byte[] buffer = new byte[4 * 1024];
+      int read = -1;
+
+      while ((read = in.read(buffer)) != -1) {
+        out.write(buffer, 0, read);
+      }
+
+    } catch (SocketException e) {
+      // download cancel..
+    } catch (Exception e) {
+      response.reset();
+      response.sendError(HttpURLConnection.HTTP_INTERNAL_ERROR, e.toString());
+    } finally {
+      if (in != null) {
+        in.close();
+      }
+      if (out != null) {
+        out.flush();
+        out.close();
+      }
+    }
+  }
+
+  /**
+   * A servlet implementation
+   */
+  public static class Servlet extends HttpServlet {
+    private static final long serialVersionUID = 1L;
+
+    public static final Log LOG = LogFactory.getLog(Servlet.class);
+
+    public static final String USAGES = "\nUSAGES:\n";
+
+    @Override
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+        throws ServletException, IOException {
+
+      final String targetUri = request.getRequestURI();
+
+      String dirName = request.getParameter("dir");
+      String fileName = request.getParameter("file");
+      String pageType = request.getParameter("type");
+      pageType = (pageType == null) ? "list" : pageType;
+      dirName = (dirName == null) ? "" : dirName;
+
+      String hamaLogDir = getLogHomeDir();
+      String logDirPath;
+
+      if (dirName == "") {
+        logDirPath = hamaLogDir;
+      } else { // Do not access upper path ('/..'', '..', '../' )
+        dirName = dirName.replaceAll("\\.\\.[/]|\\.\\.[//]|\\.\\.", "");
+        logDirPath = hamaLogDir + "/" + dirName;
+      }
+
+      String logfilePath = logDirPath + "/" + fileName;
+
+      if (pageType.equals("download")) {
+
+        LogView.downloadFile(response, logfilePath);
+
+      } else {
+
+        response.setContentType("text/html");
+        PrintWriter out = response.getWriter();
+
+        UITemplate uit = new UITemplate();
+        String tplPath = "webapp/commons/tpl/"; // UI tempalet file path
+        String tplfile = uit.load(tplPath + "tpl.logview.html"); // UI tmepalte
+                                                                 // file
+
+        HashMap<String, String> vars = new HashMap<String, String>();
+
+        String tplHead = uit.getArea(tplfile, "head");
+        String tplTail = uit.getArea(tplfile, "tail");
+
+        vars.put("title", "logview");
+        vars.put("hamaLogDir", hamaLogDir);
+
+        out.println(uit.convert(tplHead, vars));
+        vars.clear();
+
+        if (pageType.equals("list")) { // list page
+
+          String[] listArea = new String[4];
+          listArea[0] = uit.getArea(tplfile, "list0");
+          listArea[1] = uit.getArea(tplfile, "list1");
+          listArea[2] = uit.getArea(tplfile, "list2");
+          listArea[3] = uit.getArea(tplfile, "list3");
+
+          vars.put("hamaLogDir", hamaLogDir);
+          vars.put("dirName", dirName);
+          vars.put("targetUri", targetUri);
+          out.println(uit.convert(listArea[0], vars));
+          vars.clear();
+
+          List<File> arrayList = LogView.getLogFileList(logDirPath);
+          File file;
+
+          for (int i = 0; i < arrayList.size(); i++) {
+            file = arrayList.get(i);
+            vars.put("dirName", dirName);
+            vars.put("fileName", file.getName());
+            vars.put("fileLastModified",
+                new Date(file.lastModified()).toString());
+            vars.put("targetUri", targetUri);
+
+            if (file.isDirectory()) {
+              vars.put("type", "dir");
+              out.println(uit.convert(listArea[1], vars));
+            } else {
+              vars.put("fileLength", LogView.convertFileSize(file.length()));
+              vars.put("type", "file");
+              out.println(uit.convert(listArea[2], vars));
+            }
+          }
+
+          vars.clear();
+          out.println(uit.convert(listArea[3], vars));
+
+        } else if (pageType.equals("detail")) { // detail page
+
+          String[] detailArea = new String[4];
+          detailArea[0] = uit.getArea(tplfile, "detail0");
+          detailArea[1] = uit.getArea(tplfile, "detail1");
+          detailArea[2] = uit.getArea(tplfile, "detail2");
+
+          vars.put("dirName", dirName);
+          vars.put("fileName", fileName);
+          vars.put("hamaLogDir", hamaLogDir);
+          vars.put("targetUri", targetUri);
+
+          out.println(uit.convert(detailArea[0], vars));
+
+          BufferedReader br = null;
+          String logLine;
+
+          try {
+            br = new BufferedReader(new FileReader(logfilePath));
+
+            while ((logLine = br.readLine()) != null) {
+              vars.put("logLine", logLine);
+              out.println(uit.convert(detailArea[1], vars));
+            }
+
+          } catch (IOException e) {
+            e.printStackTrace();
+          } finally {
+            if (br != null) {
+              br.close();
+            }
+
+          }
+
+          out.println(uit.convert(detailArea[2], vars));
+
+        } else if (pageType.equals("tail")) { // tail page
+          String tailLine = request.getParameter("tailLine");
+          tailLine = (tailLine == null) ? "100" : tailLine;
+
+          String[] tailArea = new String[3];
+          tailArea[0] = uit.getArea(tplfile, "logtail0");
+          tailArea[1] = uit.getArea(tplfile, "logtail1");
+          tailArea[2] = uit.getArea(tplfile, "logtail2");
+
+          vars.put("hamaLogDir", hamaLogDir);
+          vars.put("dirName", dirName);
+          vars.put("fileName", fileName);
+          vars.put("tailLine", tailLine);
+          vars.put("pageType", pageType);
+          vars.put("targetUri", targetUri);
+
+          out.println(uit.convert(tailArea[0], vars));
+          vars.clear();
+
+          InputStream is = null;
+          InputStreamReader isr = null;
+          BufferedReader br = null;
+
+          try {
+
+            String tailcmd = "tail -" + tailLine + "  " + logfilePath;
+            Runtime runtime = Runtime.getRuntime();
+            Process process = runtime.exec(tailcmd);
+
+            is = process.getInputStream();
+            isr = new InputStreamReader(is);
+            br = new BufferedReader(isr);
+            String eachLine = "";
+
+            int lineNum = 0;
+            while ((eachLine = br.readLine()) != null) {
+              vars.put("lineNum", Integer.toString(++lineNum));
+              vars.put("logLine", eachLine);
+              out.println(uit.convert(tailArea[1], vars));
+            }
+
+          } catch (IOException e) {
+            e.printStackTrace();
+          } finally {
+            if (br != null) {
+              br.close();
+            }
+            if (isr != null) {
+              isr.close();
+            }
+            if (is != null) {
+              is.close();
+            }
+          }
+
+          vars.clear();
+          out.println(uit.convert(tailArea[2], vars));
+
+        }
+
+        vars.clear();
+        out.println(tplTail);
+      }
+
+    }
+
+    private static String getLogHomeDir() {
+      Map<String, String> env = System.getenv();
+      String hamaHome = env.get("HAMA_HOME");
+      String hamaLogDir = null;
+
+      if (!env.containsKey("HAMA_LOG_DIR")) {
+        hamaLogDir = hamaHome + "/logs";
+      } else {
+        hamaLogDir = env.get("HAMA_LOG_DIR");
+      }
+
+      return hamaLogDir;
+    }
+  }
+
+}

Propchange: hama/trunk/core/src/main/java/org/apache/hama/manager/LogView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: hama/trunk/core/src/main/java/org/apache/hama/manager/util/UITemplate.java
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/java/org/apache/hama/manager/util/UITemplate.java?rev=1610643&view=auto
==============================================================================
--- hama/trunk/core/src/main/java/org/apache/hama/manager/util/UITemplate.java (added)
+++ hama/trunk/core/src/main/java/org/apache/hama/manager/util/UITemplate.java Tue Jul 15 10:59:25 2014
@@ -0,0 +1,251 @@
+/**
+ * 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.hama.manager.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * UI Template utility for Hama Manager.
+ */
+public class UITemplate {
+
+  public static final Log LOG = LogFactory.getLog(UITemplate.class);
+
+  private final static String AREA_BEGIN_OPEN_TAG = "<!--{area,begin,";
+  private final static String AREA_END_OPEN_TAG = "<!--{area,end,";
+  private final static String AREA_CLOSE_TAG = "}-->";
+  private final static String[] ERROR_MESSAGE = {
+      "[Error] The template File not exist. ",
+      "[Error] The area does not exist. ",
+      "[Error] <!--{area,end,..}--> does not exist. ",
+      "[Error] <!--{area,begin,..}--> does not exist. " };
+
+  /**
+   * read template file contents
+   * 
+   * @param template fileName
+   */
+  public String load(String fileName) {
+
+    File tempalteFile = new File(fileName);
+
+    if (tempalteFile.isFile()) {
+      return loadTemplateFile(fileName);
+    } else {
+      return loadTemplateResource(fileName);
+    }
+  }
+
+  /**
+   * read template file contents
+   * 
+   * @param template fileName
+   */
+  protected String loadTemplateFile(String fileName) {
+
+    FileInputStream fis = null;
+    int bytesRemain; // the number of remaining bytes
+    StringBuilder sb = new StringBuilder();
+
+    try {
+      fis = new FileInputStream(fileName);
+
+      while ((bytesRemain = fis.available()) > 0) {
+        byte[] data = new byte[bytesRemain];
+        int bytesRead = fis.read(data);
+        if (bytesRead == -1) {
+          break;
+        }
+        sb.append(new String(data));
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    } finally {
+      if (fis != null) {
+        try {
+          fis.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * read template file contents
+   * 
+   * @param template fileName
+   */
+  protected String loadTemplateResource(String fileName) {
+
+    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+    if (classLoader == null) {
+      classLoader = this.getClass().getClassLoader();
+    }
+
+    InputStream is = classLoader.getResourceAsStream(fileName);
+    InputStreamReader isr = new InputStreamReader(is);
+    BufferedReader br = new BufferedReader(isr);
+    StringBuffer sb = new StringBuffer();
+    String line;
+
+    try {
+      while ((line = br.readLine()) != null) {
+        sb.append(line);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    } finally {
+      if (br != null) {
+        try {
+          br.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      }
+      if (isr != null) {
+        try {
+          isr.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      }
+      if (is != null) {
+        try {
+          is.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Get the data corresponding to the area in the template
+   * 
+   * @param all template file data
+   * @param areaName area name
+   */
+  public String getArea(String data, String areaName) {
+    return getAreaTemplate(data, areaName);
+  }
+
+  /**
+   * Get the data corresponding to the area in the template
+   * 
+   * @param data template file data
+   * @param areaName area name
+   */
+  protected String getAreaTemplate(String data, String areaName) {
+
+    String beginTag = AREA_BEGIN_OPEN_TAG + areaName + AREA_CLOSE_TAG;
+    String endTag = AREA_END_OPEN_TAG + areaName + AREA_CLOSE_TAG;
+
+    int beginIndex = data.indexOf(beginTag);
+    if (beginIndex == -1) {
+      return ERROR_MESSAGE[0] + areaName;
+    }
+    int endIndex = data.indexOf(endTag);
+    if (endIndex == -1) {
+      return ERROR_MESSAGE[2] + areaName;
+    }
+    return data.substring(beginIndex + beginTag.length(), endIndex);
+  }
+
+  /**
+   * Replace the value of the variable in the data area
+   * 
+   * @param area area data
+   * @param vars variables
+   */
+  public String convert(String area, HashMap<String, String> vars) {
+    return convertVariable(area, vars);
+  }
+
+  /**
+   * Replace the value of the variable in the data area
+   * 
+   * @param area area data
+   * @param variables variables
+   */
+  public String convertVariable(String area, HashMap<String, String> variables) {
+
+    StringBuffer sb = new StringBuffer();
+    String variableName, variableValue;
+
+    for (int i = 0; i < area.length(); i++) {
+      if (area.charAt(i) == '$') {
+        variableName = getVariableName(area, i);
+
+        if (variableName == null) {
+          sb.append(area.charAt(i));
+        } else {
+          variableValue = variables.get(variableName);
+          if (variableValue != null) {
+            sb.append(variableValue);
+          }
+          i += variableName.length() + 2;
+        }
+      } else {
+        sb.append(area.charAt(i));
+      }
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Replace the value of the variable in the data area
+   * 
+   * @param area area data
+   * @param pos position to start the conversion
+   */
+  private String getVariableName(String area, int pos) {
+    StringBuffer variableName = new StringBuffer("");
+    boolean inVariableName = false;
+
+    for (int i = pos + 1; i < area.length(); i++) {
+      char ch = area.charAt(i);
+      if ((ch != '{') && (!inVariableName)) {
+        return null;
+      }
+      if (inVariableName) {
+        if (ch == '}') {
+          return variableName.toString();
+        }
+        variableName.append(ch);
+      }
+      inVariableName = true;
+    }
+    return null;
+  }
+
+}

Propchange: hama/trunk/core/src/main/java/org/apache/hama/manager/util/UITemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: hama/trunk/core/src/main/java/org/apache/hama/util/BSPServletUtil.java
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/java/org/apache/hama/util/BSPServletUtil.java?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/core/src/main/java/org/apache/hama/util/BSPServletUtil.java (original)
+++ hama/trunk/core/src/main/java/org/apache/hama/util/BSPServletUtil.java Tue Jul 15 10:59:25 2014
@@ -61,7 +61,7 @@ public class BSPServletUtil extends Serv
     if (jobs.length > 0) {
       sb.append("<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\">\n");
       sb.append("<tr><th>Jobid</th>" + "<th>User</th>" + "<th>Name</th>"
-          + "<th>SuperSteps</th>" + "<th>Tasks</th>" + "<th>Starttime</th>"
+          + "<th>SuperSteps</th>" + "<th>Tasks</th>" + "<th>Starttime</th>" + "<th>Job Logs</th>"
           + "</tr>\n");
       for (JobStatus status : jobs) {
         sb.append("<tr><td><a href=\"bspjob.jsp?jobid=")
@@ -77,6 +77,10 @@ public class BSPServletUtil extends Serv
         sb.append(status.getNumOfTasks());
         sb.append("</td><td>");
         sb.append(new Date(status.getStartTime()));
+        sb.append("</td><td>");
+        sb.append("<a href=\"/logView?dir=tasklogs/");
+        sb.append(status.getJobID());
+        sb.append("\">view</a>");
         sb.append("</td></tr>\n");
       }
       sb.append("</table>");
@@ -90,13 +94,12 @@ public class BSPServletUtil extends Serv
   public static String generateGroomsTable(String type, ClusterStatus status,
       BSPMaster master) throws IOException {
     StringBuilder sb = new StringBuilder();
-    sb.append("<center>\n");
-    sb.append("<table border=\"2\" cellpadding=\"5\" cellspacing=\"2\">\n");
-    sb.append("<tr><td align=\"center\" colspan=\"6\"><b>Groom Servers</b></td></tr>\n");
-    sb.append("<tr><td><b>Name</b></td>"
-        + "<td><b>Host</b></td>"
-        + "<td><b># maximum tasks</b></td><td><b># current running tasks</b></td>"
-        + "<td><b># current failures</b></td>" + "<td><b>Last seen</b></td>"
+    sb.append("<table border=\"1\" cellpadding=\"5\" cellspacing=\"2\">\n");
+    sb.append("<tr><th align=\"center\" colspan=\"6\"><b>Groom Servers</b></th></tr>\n");
+    sb.append("<tr><th><b>Name</b></th>"
+        + "<th><b>Host</b></th>"
+        + "<th><b># maximum tasks</b></th><th><b># current running tasks</b></th>"
+        + "<th><b># current failures</b></th>" + "<th><b>Last seen</b></th>"
         + "</tr>\n");
     for (Entry<String, GroomServerStatus> entry : status
         .getActiveGroomServerStatus().entrySet()) {
@@ -112,7 +115,6 @@ public class BSPServletUtil extends Serv
       sb.append("</tr>\n");
     }
     sb.append("</table>\n");
-    sb.append("</center>\n");
     return sb.toString();
   }
 

Modified: hama/trunk/core/src/main/resources/webapp/bspmaster/bspjob.jsp
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/bspmaster/bspjob.jsp?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/bspmaster/bspjob.jsp (original)
+++ hama/trunk/core/src/main/resources/webapp/bspmaster/bspjob.jsp Tue Jul 15 10:59:25 2014
@@ -28,15 +28,18 @@
 %>
 
 <html>
-
+<head>
 <title>Hama BSP Job Summary</title>
-
+<link rel="stylesheet" href="/static/hama.css" />
+</head>
 <body>
   <h1><%=status.getName()%></h1>
-
-  <b>State: </b>  <%=state.toString() %> 
-  
-  <br/> <br/>
+  <div class="block-detail">
+    <ul>
+      <li><span>State : </span><%=state.toString() %></li>
+  </div>
+  <br/>
+  <div class="block-list">
   <table border="1" cellpadding="6" cellspacing="0">
     <tr>
       <th>Name</th>
@@ -45,6 +48,7 @@
       <th>Tasks</th>
       <th>StartTime</th>
       <th>FinishTime</th>
+      <th>Job Logs</th>      
     </tr>
 
     <tr>
@@ -56,11 +60,13 @@
       <td>
         <% if(status.getFinishTime() != 0L) {out.write(new Date(status.getFinishTime()).toString());} %>
       </td>
+      <td><a href="/logView?dir=tasklogs/<%=idString%>">view</a></td>      
     </tr>
 
   </table>
-  
-   <br/> <br/>
+  </div>
+  <br/>
+  <div class="block-list">  
   <table border="1" cellpadding="6" cellspacing="0">
     <tr>
       <th><br/></th>
@@ -101,9 +107,13 @@
     }
     %>
   </table>
-
+  </div>
+  <p/>
+  <hr>
+    <h2>Job Logs</h2>
+    <a href="/logView?dir=tasklogs/<%=idString%>">Log</a> directory
   <hr>
-  <a href="bspmaster.jsp">Back to BSPMaster</a>
+  <a href="bspmaster.jsp"><i>Back to BSPMaster</i></a>
 
   <%
     out.println(BSPServletUtil.htmlFooter());

Modified: hama/trunk/core/src/main/resources/webapp/bspmaster/bspmaster.jsp
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/bspmaster/bspmaster.jsp?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/bspmaster/bspmaster.jsp (original)
+++ hama/trunk/core/src/main/resources/webapp/bspmaster/bspmaster.jsp Tue Jul 15 10:59:25 2014
@@ -35,9 +35,9 @@
         .format(((double) (status.getMaxTasks()) / status
             .getGroomServers())) : "-";
     out.print("<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\">\n"
-        + "<tr>" + "<th>Groom Servers</th><th>BSP Task Capacity</th>"
+        + "<tr>" + "<th><a href=\"machines.jsp?type=active\">Groom Servers</a></th><th>BSP Task Capacity</th>"
         + "<th>Avg. Tasks/Node</th>"
-        + "<th>Blacklisted Nodes</th></tr>\n");
+        + "<th><a href=\"machines.jsp?type=blacklisted\">Blacklisted Nodes</a></th></tr>\n");
     out.print("<tr><td><a href=\"machines.jsp?type=active\">"
         + status.getActiveGroomNames().size() + "</a></td><td>"
         + status.getMaxTasks() + "</td><td>" + tasksPerNode
@@ -51,38 +51,47 @@
 <html>
 <head>
 <title><%=trackerName%> Hama BSP Administration</title>
-<!--  <link rel="stylesheet" type="text/css" href="/static/hadoop.css">-->
+<link rel="stylesheet" href="static/hama.css" />
 </head>
 <body>
 
 <h1><%=trackerName%> Hama BSP Administration</h1>
-
-<b>State:</b>
-<%=status.getBSPMasterState()%><br>
-<b>Started:</b>
-<%=new Date(tracker.getStartTime())%><br>
-<b>Version:</b>
-<%=VersionInfo.getVersion()%><br>
-<b>Compiled By:</b>
-<%=VersionInfo.getUser()%><br>
-<b>Compiled At Time:</b>
-<%=VersionInfo.getDate()%><br>
-<b>Identifier:</b>
-<%=tracker.getBSPMasterIdentifier()%><br>
+<hr>
+<div class="block-detail">
+<ul>
+    <li><span>State : </span><%=status.getBSPMasterState()%></li>
+    <li><span>Started : </span> <%=new Date(tracker.getStartTime())%></li>
+    <li><span>Version : </span> <%=VersionInfo.getVersion()%></li>
+    <li><span>Compiled By : </span> <%=VersionInfo.getUser()%></li>     
+    <li><span>Compiled At Time : </span> <%=VersionInfo.getDate()%></li>         
+    <li><span>Identifier : </span> <%=tracker.getBSPMasterIdentifier()%></li>  
+</ul>
+</div>
 
 <hr>
+<h2 id="cluster_summary">Cluster Summary</h2>
+<div class="block-list">
 <%
   generateSummaryTable(out, status, tracker);
 %>
+</div>
 <hr />
 
 <h2 id="running_jobs">Running Jobs</h2>
+<div class="block-list">
 <%=BSPServletUtil.generateJobTable("Running", runningJobs,
           30, 0)%>
+</div>
 <hr> 
 <h2 id="running_jobs">All Jobs History</h2>
+<div class="block-list">
 <%=BSPServletUtil.generateJobTable("All", allJobs,
           30, 0)%>
+</div>
+<p/>
+<hr>
+<h2>Local Logs</h2>
+<a href="/logView">Log</a> directory
 <%
   out.println(BSPServletUtil.htmlFooter());
 %>

Modified: hama/trunk/core/src/main/resources/webapp/bspmaster/index.html
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/bspmaster/index.html?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/bspmaster/index.html (original)
+++ hama/trunk/core/src/main/resources/webapp/bspmaster/index.html Tue Jul 15 10:59:25 2014
@@ -19,6 +19,7 @@
 
 <head>
 <title>Hama Administration</title>
+<link rel="stylesheet" href="/static/hama.css" />
 </head>
 
 <body>

Modified: hama/trunk/core/src/main/resources/webapp/bspmaster/machines.jsp
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/bspmaster/machines.jsp?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/bspmaster/machines.jsp (original)
+++ hama/trunk/core/src/main/resources/webapp/bspmaster/machines.jsp Tue Jul 15 10:59:25 2014
@@ -28,14 +28,17 @@
 %>
 
 <html>
-
+<head>
 <title><%=trackerName%> Hama Machine List</title>
-
+<link rel="stylesheet" href="/static/hama.css" />
+</head>
 <body>
 <h1><a href="bspmaster.jsp"><%=trackerName%></a> Hama Machine List</h1>
-
+<hr/>
 <h2>Grooms</h2>
+<div class="block-list">
 <%
   out.println(BSPServletUtil.generateGroomsTable(type, status, tracker));
   out.println(BSPServletUtil.htmlFooter());
-%>
\ No newline at end of file
+%>
+</div>
\ No newline at end of file

Added: hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.configlist.html
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.configlist.html?rev=1610643&view=auto
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.configlist.html (added)
+++ hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.configlist.html Tue Jul 15 10:59:25 2014
@@ -0,0 +1,71 @@
+<!--
+   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.
+-->
+<!--{area,begin,head}-->
+<html>
+<head>
+<title>${title}</title>
+<link rel="stylesheet" href="./static/hama.css" />
+<script type="text/javascript" src="./static/hama.js"></script>
+</head>
+<body>
+<h1>Configuration</h1>
+<hr/>
+<div class="block-detail">
+<ul>
+    <li><a href="#hama"><i>Hama Configuration</i></a></li>
+    <li><a href="#system"><i>System Properties</i></a></li>
+    <li><a href="#env"><i>Environment Variables</i></a></li>        
+</ul>
+</div>
+<!--{area,end,head}-->
+
+<!--{area,begin,config0}-->
+<hr>
+<h2 id="${ConfigId}">${ConfigName}</h2>
+<div class="block-list-prop">
+<table>
+<thead>
+  <tr>
+    <th>name</th>
+    <th>value</th>    
+  </tr>
+</thead>  
+<tbody>
+<!--{area,end,config0}-->
+
+<!--{area,begin,config1}-->
+  <tr>
+    <td>${name}</td>
+    <td>${value}</td>    
+  </tr>
+<!--{area,end,config1}-->
+
+<!--{area,begin,config2}-->
+</tbody>
+</table>
+</div>
+<!--{area,end,config2}-->
+
+<!--{area,begin,tail}-->
+<hr />
+<div id="footer" class="contents">
+<a href='http://hama.apache.org/'>Apache Hama</a>
+</div>
+</body></html>
+</body>
+</html>
+<!--{area,end,tail}-->
\ No newline at end of file

Propchange: hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.configlist.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.logview.html
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.logview.html?rev=1610643&view=auto
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.logview.html (added)
+++ hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.logview.html Tue Jul 15 10:59:25 2014
@@ -0,0 +1,174 @@
+<!--
+   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.
+-->
+<!--{area,begin,head}-->
+<html>
+<head>
+<title>${title}</title>
+<link rel="stylesheet" href="./static/hama.css" />
+<script type="text/javascript" src="./static/hama.js"></script>
+</head>
+<body>
+<h1>Hama Logs(${hamaLogDir})</h1>
+<hr/>
+<!--{area,end,head}-->
+
+<!--{area,begin,list0}-->
+<h2>Contents of directory : ${dirName}</h2>
+<div>
+<form action="${targetUri}" method="get" name="goto">
+<div class="block-search">
+    <table>
+    <tbody>
+       <tr>
+          <th>Goto</th>
+          <td>
+            <input name="dir" type="text" size="30" id="dir" value="${dirName}"/>
+            <input name="go" type="submit" value="go"/>
+          </td>
+       </tr>
+    </tbody>
+    </table>
+</div>
+</form>
+</div>
+<div class="block-list-log">
+<table class="full-width">
+<thead>
+  <tr>
+    <th>filename</th>
+    <th>type</th>    
+    <th>size</th>
+    <th>lastModified</th>
+    <th>etc</th>
+  </tr>
+</thead>  
+<tbody>
+<!--{area,end,list0}-->
+
+<!--{area,begin,list1}-->
+  <tr>
+    <td><a href="${targetUri}?dir=${dirName}/${fileName}">${fileName}</a></td>
+    <td>${type}</td>    
+    <td></td>
+    <td>${fileLastModified}</td>
+    <td>
+      <a href="${targetUri}?dir=${dirName}/${fileName}" class="link-container"><span class="link-title">view</span></a>
+    </td>
+    
+  </tr>
+<!--{area,end,list1}-->
+
+<!--{area,begin,list2}-->
+  <tr>
+    <td><span><a href="${targetUri}?dir=${dirName}&file=${fileName}&type=detail">${fileName}</a></span></td>
+    <td>${type}</td>    
+    <td>${fileLength}</td>
+    <td>${fileLastModified}</td>
+    <td>
+      <a href="${targetUri}?dir=${dirName}&file=${fileName}&type=detail" class="link-container"><span class="link-title">view</span></a>
+      <a href="${targetUri}?dir=${dirName}&file=${fileName}&type=tail" class="link-container"><span class="link-title">tail</span></a>
+      <a href="${targetUri}?dir=${dirName}&file=${fileName}&type=download" class="link-container"><span class="link-title">download</span></a>
+    </td>
+  </tr>
+<!--{area,end,list2}-->
+
+<!--{area,begin,list3}-->
+</tbody>
+</table>
+</div>
+<!--{area,end,list3}-->
+
+<!--{area,begin,detail0}-->
+<h2>File : ${dirName}/${fileName}</h2>
+
+<ul>
+    <li><a href="${targetUri}?dir=${dirName}"><i>Go back to dir listing</i></a></li>
+</ul>
+<pre>
+<!--{area,end,detail0}-->
+
+<!--{area,begin,detail1}-->
+${logLine}
+<!--{area,end,detail1}-->
+
+<!--{area,begin,detail2}-->
+</pre>
+<!--{area,end,detail2}-->
+
+<!--{area,begin,logtail0}-->
+<h2>File: ${dirName}/${fileName}</h2>
+
+<div class="block-detail">
+  <ul>
+    <li><a href="${targetUri}?dir=${logDirName}"><i>Go back to dir listing</i></a></li>
+  </ul>
+</div>
+
+<div id=search>
+<form action="${targetUri}" method="get" name="goto">
+  <div class="block-search">
+    <table>
+    <tbody>
+       <tr>
+          <th>line</th>
+          <td>
+          <input name="tailLine" type="text" width="50" id="tailLine" value="${tailLine}"/><input name="go" type="submit" value="go"/>
+          <input name="type" type="hidden" value="${pageType}" />          
+          <input name="dir" type="hidden" value="${dirName}" />
+          <input name="file" type="hidden" value="${fileName}" />          
+          </td>
+       </tr>
+    </tbody>
+    </table>
+  </div>
+</form>
+</div>
+<div class="block-code">
+<table>
+<thead>
+  <tr>
+    <th>line</th>
+    <th>code</th>
+  </tr>
+</thead>  
+<tbody>
+<tbody>
+<!--{area,end,logtail0}-->
+
+<!--{area,begin,logtail1}-->
+  <tr>
+    <td class="line">${lineNum}</td>
+    <td class="code">${logLine}</td>
+  </tr>
+<!--{area,end,logtail1}-->
+
+<!--{area,begin,logtail2}-->
+</tbody>
+</table>
+</div>  
+<!--{area,end,logtail2}-->
+
+
+<!--{area,begin,tail}-->
+<hr />
+<div id="footer" class="contents">
+<a href='http://hama.apache.org/'>Apache Hama</a>
+</div>
+</body></html>
+</body>
+</html>
+<!--{area,end,tail}-->
\ No newline at end of file

Propchange: hama/trunk/core/src/main/resources/webapp/commons/tpl/tpl.logview.html
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: hama/trunk/core/src/main/resources/webapp/groomserver/groomserver.jsp
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/groomserver/groomserver.jsp?rev=1610643&r1=1610642&r2=1610643&view=diff
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/groomserver/groomserver.jsp (original)
+++ hama/trunk/core/src/main/resources/webapp/groomserver/groomserver.jsp Tue Jul 15 10:59:25 2014
@@ -33,14 +33,17 @@
 %>
 
 <html>
-
+<head>
 <title><%= groomName %> - Server Status</title>
+<link rel="stylesheet" href="/static/hama.css" />
+</head>
 <body>
-<h2><%= groomName %></h2>
+<h1><%= groomName %></h1>
 <hr>
 <h2>Running tasks</h2>
-<table border=2 cellpadding="5" cellspacing="2">
-<tr><td align="center">Task Attempts</td><td>Status</td>
+<div class="block-list">
+<table border=1 cellpadding="5" cellspacing="2">
+<tr><th align="center">Task Attempts</th><th>Status</th>
     </tr>
   <%
      Iterator itr = groom.getRunningTaskStatuses().iterator();
@@ -52,9 +55,10 @@
      }
   %>
 </table>
+</div>
 <hr>
 <h2>Local Logs</h2>
-<a href="/logs/">Log</a> directory
+<a href="/logView">Log</a> directory
 
 <%
   out.println(BSPServletUtil.htmlFooter());

Added: hama/trunk/core/src/main/resources/webapp/static/hama.css
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/main/resources/webapp/static/hama.css?rev=1610643&view=auto
==============================================================================
--- hama/trunk/core/src/main/resources/webapp/static/hama.css (added)
+++ hama/trunk/core/src/main/resources/webapp/static/hama.css Tue Jul 15 10:59:25 2014
@@ -0,0 +1,174 @@
+@charset "utf-8";
+/*
+  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.
+*/
+
+body {
+    margin: 10px 20px;
+    font: 90% Arial, sans-serif; 
+    color : #333;
+    background: #fff;
+}
+
+a:link, a:visited { color: #74240f; text-decoration: none; }
+
+a:hover, a:active { color: #888800; text-decoration: underline; }
+
+h1,h2,h3,h4,h5 {    color: #74240f; }
+
+div { display: block; }
+
+table { border-collapse : collapse; border-spacing:0; font-size: 11pt; } 
+
+table th, table td { white-space: nowrap; height: 24px; padding: 5px; }
+
+table th { font-weight: bold; text-align: center; }
+
+ul { padding-left : 20px; }
+
+li { }
+
+hr {
+    height: 1px;
+    border: none;
+    background: #e0e0e0;
+}
+
+pre {
+    border: 1px solid #7F9DB9;
+    background-color: #f5f5f5;
+    padding: 5px;
+    width: 100%;
+    height: 80%;
+    white-space: pre-wrap; /* css-3 */
+    white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
+    white-space: -pre-wrap; /* Opera 4-6 */
+    white-space: -o-pre-wrap; /* Opera 7 */
+    word-wrap: break-work; /* IE 5.5+ */
+    overflow-y: scroll;
+}
+
+.block-list { margin 0 0 10px 0; }
+.block-list table { border-top: solid 2px #74240f; border-bottom: solid 1px #c9c9c9; }
+.block-list table th,
+.block-list table td { border: 1px solid #e8e8e8; }
+.block-list table th { background-color: #f6f6f6; }
+
+.block-list-prop { margin 0 0 10px 0 }
+.block-list-prop table {
+    border-top: solid 2px #74240f;
+    border-bottom: solid 1px #c9c9c9;
+    width : 100%;
+}
+.block-list-prop table th,
+.block-list-prop table td { white-space: normal;    border: 1px solid #e8e8e8; }
+.block-list-prop table th { background-color: #f6f6f6; }
+
+.block-list-log { margin 0 0 10px 0; }
+.block-list-log table {
+    border-top: solid 2px #74240f;
+    border-bottom: solid 1px #c9c9c9;
+    width : 100%;
+}
+.block-list-log table th,
+.block-list-log table td { border: 1px solid #e8e8e8; }
+.block-list-log table th { background-color: #f6f6f6; }
+
+
+.block-detail { margin 0 0 10px 0; }
+.block-detail table { border-top: solid 2px #74240f; }
+.block-detail table th,
+.block-detail table td {
+    border: 1px solid #e8e8e8;
+    height: 26px;
+    padding: 0 5px;
+    border-left: none;
+    border-right: none;
+    white-space: nowarp;    
+}
+.block-detail table th {
+    background-color: #f6f6f6;
+    text-align: left;
+}
+.block-detail ul { list-style : none; padding-left : 0px; }
+.block-detail li { line-height : 20px; } 
+.block-detail li span { font-weight : bold; color : #404040; }
+
+.block-search {
+    margin : -2px 0 10px 0;
+    border : 1px solid #e0e0e0;
+    background : #f4f2f3;
+}
+.block-search div { position : relative; }
+.block-search table { background-color : #ffffff; }
+.block-search table th {
+    background-color : #f4f2f3;
+    white-space : nowrap;
+    padding-left : 15px;
+    font-weight : normal;
+    color : #494949;
+    border : none;
+}
+.block-search table td {
+    background-color : #f4f2f3;
+    padding : 7px 10px 7px 5px;
+    border : none;
+}
+
+.block-code { margin 0 0 10px 0; }
+.block-code table {
+    font-size: 9pt;
+    border-top : solid 2px #74240f;
+    border-bottom : solid 1px #c9c9c9;
+    width : 100%;
+}
+.block-code table th,
+.block-code table td {
+    height : 20px;
+    padding : 5px;
+    white-space : pre-wrap;
+    border-left : 1px solid #e8e8e8;
+    border-right : 1px solid #e8e8e8;  
+}
+.block-code table th { background-color : #f6f6f6; border-bottom : 1px solid #e8e8e8; }
+.block-code table td.line { background-color : #f9f9f9; text-align : right; padding-right : 5px; }
+.block-code table td.code { background-color : #f9f9f9; }
+
+
+.link-container {
+    text-decoration : none;
+    border : 1px solid #f5f5f5;
+    display : inline-block;
+    margin : 0;
+    text-align : center;
+    padding : 0 5px;
+    outline : 0;
+}
+.link-container:hover {
+    text-decoration : none;
+    border-color : #6db33f;
+    box-shadow : 0 0 2px #888800;
+}
+.link-title {
+    font-size : 14px;
+    line-height : 14px;
+    margin : 0;
+}
+
+#footer {
+    padding: 1em;
+    text-align: center;
+}
\ No newline at end of file

Propchange: hama/trunk/core/src/main/resources/webapp/static/hama.css
------------------------------------------------------------------------------
    svn:eol-style = native

Added: hama/trunk/core/src/test/java/org/apache/hama/manager/TestLogView.java
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/test/java/org/apache/hama/manager/TestLogView.java?rev=1610643&view=auto
==============================================================================
--- hama/trunk/core/src/test/java/org/apache/hama/manager/TestLogView.java (added)
+++ hama/trunk/core/src/test/java/org/apache/hama/manager/TestLogView.java Tue Jul 15 10:59:25 2014
@@ -0,0 +1,40 @@
+/**
+ * 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.hama.manager;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hama.manager.util.UITemplate;
+
+public class TestLogView extends TestCase {
+
+  public static final Log LOG = LogFactory.getLog(UITemplate.class);
+
+  public void testconvertFileSize() throws Exception {
+
+    assertEquals("File size 1024.", LogView.convertFileSize(1024), "1 KB");
+    assertEquals("File size 1048576.", LogView.convertFileSize(1048576), "1 MB");
+    assertEquals("File size 1073741824.", LogView.convertFileSize(1073741824),
+        "1 GB");
+    assertEquals("File size 1099511627776L.",
+        LogView.convertFileSize(1099511627776L), "1 TB");
+    assertEquals("File size 0.", LogView.convertFileSize(0), "0 bytes");
+  }
+}

Propchange: hama/trunk/core/src/test/java/org/apache/hama/manager/TestLogView.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: hama/trunk/core/src/test/java/org/apache/hama/manager/util/TestUITemplate.java
URL: http://svn.apache.org/viewvc/hama/trunk/core/src/test/java/org/apache/hama/manager/util/TestUITemplate.java?rev=1610643&view=auto
==============================================================================
--- hama/trunk/core/src/test/java/org/apache/hama/manager/util/TestUITemplate.java (added)
+++ hama/trunk/core/src/test/java/org/apache/hama/manager/util/TestUITemplate.java Tue Jul 15 10:59:25 2014
@@ -0,0 +1,54 @@
+/**
+ * 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.hama.manager.util;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class TestUITemplate extends TestCase {
+
+  public static final Log LOG = LogFactory.getLog(UITemplate.class);
+
+  String tplPath = "webapp/commons/tpl/";
+  String tplFileName = "tpl.configlist.html";
+
+  public void testload() throws Exception {
+
+    UITemplate uit = new UITemplate();
+
+    String tplfile = uit.load(tplPath + tplFileName);
+
+    assertTrue(tplfile.length() > 0);
+  }
+  
+  public void testGetArea() throws Exception {
+
+    UITemplate uit = new UITemplate();
+
+    String tplfile = uit.load(tplPath + tplFileName);
+
+    String tplHead = uit.getArea(tplfile, "head");
+    String tplTail = uit.getArea(tplfile, "tail");
+
+    assertTrue(tplHead.length() > 0);
+    assertTrue(tplTail.length() > 0);    
+  }
+
+}

Propchange: hama/trunk/core/src/test/java/org/apache/hama/manager/util/TestUITemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message