View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.chukwa.hicc;
20  
21  
22  import java.io.*;
23  import java.nio.charset.Charset;
24  import java.util.*;
25  
26  import javax.servlet.*;
27  import javax.servlet.http.*;
28  
29  import java.sql.*;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.apache.hadoop.chukwa.util.XssFilter;
34  import org.json.simple.JSONArray;
35  import org.json.simple.JSONObject;
36  import org.json.simple.JSONValue;
37  import org.apache.hadoop.chukwa.util.ExceptionUtil;
38  
39  public class Workspace extends HttpServlet {
40    public static final long serialVersionUID = 101L;
41    private static final Log log = LogFactory.getLog(Workspace.class);
42    private String path = System.getenv("CHUKWA_DATA_DIR");
43    private JSONObject hash = new JSONObject();
44    transient private XssFilter xf;
45  
46    @Override  
47    protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
48      resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); 
49    }
50  
51    public void doGet(HttpServletRequest request, HttpServletResponse response)
52        throws IOException, ServletException {
53      xf = new XssFilter(request);
54      response.setContentType("text/plain");
55      String method = xf.getParameter("method");
56      if (method.equals("get_views_list")) {
57        getViewsList(request, response);
58      }
59      if (method.equals("get_view")) {
60        getView(request, response);
61      }
62      if (method.equals("save_view")) {
63        saveView(request, response);
64      }
65      if (method.equals("change_view_info")) {
66        changeViewInfo(request, response);
67      }
68      if (method.equals("get_widget_list")) {
69        getWidgetList(request, response);
70      }
71      if (method.equals("clone_view")) {
72        cloneView(request, response);
73      }
74      if (method.equals("delete_view")) {
75        deleteView(request, response);
76      }
77    }
78  
79    public void doPost(HttpServletRequest request, HttpServletResponse response)
80        throws IOException, ServletException {
81      doGet(request, response);
82    }
83  
84    static public String getContents(File aFile) {
85      // ...checks on aFile are elided
86      StringBuffer contents = new StringBuffer();
87  
88      try {
89        // use buffering, reading one line at a time
90        // FileReader always assumes default encoding is OK!
91        BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(aFile.getAbsolutePath()), Charset.forName("UTF-8")));
92        try {
93          String line = null; // not declared within while loop
94          /*
95           * readLine is a bit quirky : it returns the content of a line MINUS the
96           * newline. it returns null only for the END of the stream. it returns
97           * an empty String if two newlines appear in a row.
98           */
99          while ((line = input.readLine()) != null) {
100           contents.append(line);
101           contents.append(System.getProperty("line.separator"));
102         }
103       } finally {
104         input.close();
105       }
106     } catch (IOException ex) {
107       ex.printStackTrace();
108     }
109 
110     return contents.toString();
111   }
112 
113   public void setContents(String fName, String buffer) {
114     try {
115       BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fName), Charset.forName("UTF-8")));
116       out.write(buffer);
117       out.close();
118     } catch (Exception e) {
119       System.err.println("Error: " + e.getMessage());
120     }
121   }
122 
123   public void cloneView(HttpServletRequest request, HttpServletResponse response)
124       throws IOException, ServletException {
125     PrintWriter out = response.getWriter();
126     String name = xf.getParameter("name");
127     String template = xf.getParameter("clone_name");
128     File aFile = new File(path + "/views/" + template);
129     String config = getContents(aFile);
130     int i = 0;
131     boolean check = true;
132     while (check) {
133       String tmpName = name;
134       if (i > 0) {
135         tmpName = name + i;
136       }
137       File checkFile = new File(path + "/views/" + tmpName + ".view");
138       check = checkFile.exists();
139       if (!check) {
140         name = tmpName;
141       }
142       i = i + 1;
143     }
144     setContents(path + "/views/" + name + ".view", config);
145     File deleteCache = new File(path + "/views/workspace_view_list.cache");
146     if(!deleteCache.delete()) {
147       log.warn("Can not delete "+path + "/views/workspace_view_list.cache");
148     }
149     genViewCache(path + "/views");
150     aFile = new File(path + "/views/workspace_view_list.cache");
151     String viewsCache = getContents(aFile);
152     out.println(viewsCache);
153   }
154 
155   public void deleteView(HttpServletRequest request,
156       HttpServletResponse response) throws IOException, ServletException {
157     String name = xf.getParameter("name");
158     File aFile = new File(path + "/views/" + name + ".view");
159     if(!aFile.delete()) {
160       log.warn("Can not delete " + path + "/views/" + name + ".view");
161     }
162     File deleteCache = new File(path + "/views/workspace_view_list.cache");
163     if(!deleteCache.delete()) {
164       log.warn("Can not delete "+path + "/views/workspace_view_list.cache");
165     }
166     genViewCache(path + "/views");
167   }
168 
169   public void getViewsList(HttpServletRequest request,
170       HttpServletResponse response) throws IOException, ServletException {
171     PrintWriter out = response.getWriter();
172     genViewCache(path + "/views");
173     File aFile = new File(path + "/views/workspace_view_list.cache");
174     String viewsCache = getContents(aFile);
175     out.println(viewsCache);
176   }
177 
178   public void getView(HttpServletRequest request, HttpServletResponse response)
179       throws IOException, ServletException {
180     PrintWriter out = response.getWriter();
181     String id = xf.getParameter("id");
182     genViewCache(path + "/views");
183     File aFile = new File(path + "/views/" + id + ".view");
184     String view = getContents(aFile);
185     out.println(view);
186   }
187 
188   public void changeViewInfo(HttpServletRequest request,
189       HttpServletResponse response) throws IOException, ServletException {
190     PrintWriter out = response.getWriter();
191     String id = xf.getParameter("name");
192     String config = request.getParameter("config");
193     try {
194       JSONObject jt = (JSONObject) JSONValue.parse(config);
195       File aFile = new File(path + "/views/" + id + ".view");
196       String original = getContents(aFile);
197       JSONObject updateObject = (JSONObject) JSONValue.parse(original);
198       updateObject.put("description", jt.get("description"));
199       setContents(path + "/views/" + id + ".view", updateObject.toString());
200       if (!rename(id, jt.get("description").toString())) {
201         throw new Exception("Rename view file failed");
202       }
203       File deleteCache = new File(path + "/views/workspace_view_list.cache");
204       if(!deleteCache.delete()) {
205         log.warn("Can not delete "+path + "/views/workspace_view_list.cache");
206       }
207       genViewCache(path + "/views");
208       out.println("Workspace is stored successfully.");
209     } catch (Exception e) {
210       out.println("Workspace store failed.");
211     }
212   }
213 
214   public void saveView(HttpServletRequest request, HttpServletResponse response)
215       throws IOException, ServletException {
216     PrintWriter out = response.getWriter();
217     String id = xf.getParameter("name");
218     String config = request.getParameter("config");
219     setContents(path + "/views/" + id + ".view", config);
220     out.println("Workspace is stored successfully.");
221   }
222 
223   public void getWidgetList(HttpServletRequest request,
224       HttpServletResponse response) throws IOException, ServletException {
225     PrintWriter out = response.getWriter();
226     genWidgetCache(path + "/descriptors");
227     File aFile = new File(path + "/descriptors/workspace_plugin.cache");
228     String viewsCache = getContents(aFile);
229     out.println(viewsCache);
230   }
231 
232   private void genViewCache(String source) {
233     File cacheFile = new File(source + "/workspace_view_list.cache");
234     if (!cacheFile.exists()) {
235       File dir = new File(source);
236       File[] filesWanted = dir.listFiles(new FilenameFilter() {
237         public boolean accept(File dir, String name) {
238           return name.endsWith(".view");
239         }
240       });
241       if(filesWanted!=null) {
242         JSONObject[] cacheGroup = new JSONObject[filesWanted.length];
243         for (int i = 0; i < filesWanted.length; i++) {
244           String buffer = getContents(filesWanted[i]);
245           try {
246             JSONObject jt = (JSONObject) JSONValue.parse(buffer);
247             String fn = filesWanted[i].getName();
248             jt.put("key", fn.substring(0, (fn.length() - 5)));
249             cacheGroup[i] = jt;
250           } catch (Exception e) {
251             log.debug(ExceptionUtil.getStackTrace(e));
252           }
253         }
254         String viewList = convertObjectsToViewList(cacheGroup);
255         setContents(source + "/workspace_view_list.cache", viewList);
256       }
257     }
258   }
259 
260   public String convertObjectsToViewList(JSONObject[] objArray) {
261     JSONArray jsonArr = new JSONArray();
262     JSONObject permission = new JSONObject();
263     JSONObject user = new JSONObject();
264     try {
265       permission.put("read", 1);
266       permission.put("modify", 1);
267       user.put("all", permission);
268     } catch (Exception e) {
269       System.err.println("JSON Exception: " + e.getMessage());
270     }
271     for (int i = 0; i < objArray.length; i++) {
272       try {
273         JSONObject jsonObj = new JSONObject();
274         jsonObj.put("key", objArray[i].get("key"));
275         jsonObj.put("description", objArray[i].get("description"));
276         jsonObj.put("owner", "");
277         jsonObj.put("permission", user);
278         jsonArr.add(jsonObj);
279       } catch (Exception e) {
280         System.err.println("JSON Exception: " + e.getMessage());
281       }
282     }
283     return jsonArr.toString();
284   }
285 
286   private void genWidgetCache(String source) {
287     File cacheFile = new File(source + "/workspace_plugin.cache");
288     File cacheDir = new File(source);
289     if (!cacheFile.exists()
290         || cacheFile.lastModified() < cacheDir.lastModified()) {
291       File dir = new File(source);
292       File[] filesWanted = dir.listFiles(new FilenameFilter() {
293         public boolean accept(File dir, String name) {
294           return name.endsWith(".descriptor");
295         }
296       });
297       if(filesWanted!=null) {
298         JSONObject[] cacheGroup = new JSONObject[filesWanted.length];
299         for (int i = 0; i < filesWanted.length; i++) {
300           String buffer = getContents(filesWanted[i]);
301           try {
302             JSONObject jt = (JSONObject) JSONValue.parse(buffer);
303             cacheGroup[i] = jt;
304           } catch (Exception e) {
305             log.debug(ExceptionUtil.getStackTrace(e));
306           }
307         }
308         String widgetList = convertObjectsToWidgetList(cacheGroup);
309         setContents(source + "/workspace_plugin.cache", widgetList);
310       }
311     }
312   }
313 
314   public String convertObjectsToWidgetList(JSONObject[] objArray) {
315     JSONObject jsonObj = new JSONObject();
316     JSONArray jsonArr = new JSONArray();
317     for (int i = 0; i < objArray.length; i++) {
318       jsonArr.add(objArray[i]);
319     }
320     try {
321       jsonObj.put("detail", jsonArr);
322     } catch (Exception e) {
323       System.err.println("JSON Exception: " + e.getMessage());
324     }
325     for (int i = 0; i < objArray.length; i++) {
326       try {
327         String[] categoriesArray = objArray[i].get("categories").toString()
328             .split(",");
329         hash = addToHash(hash, categoriesArray, objArray[i]);
330       } catch (Exception e) {
331         System.err.println("JSON Exception: " + e.getMessage());
332       }
333     }
334     try {
335       jsonObj.put("children", hash);
336     } catch (Exception e) {
337       System.err.println("JSON Exception: " + e.getMessage());
338     }
339     return jsonObj.toString();
340   }
341 
342   public JSONObject addToHash(JSONObject hash, String[] categoriesArray,
343       JSONObject obj) {
344     JSONObject subHash = hash;
345     for (int i = 0; i < categoriesArray.length; i++) {
346       String id = categoriesArray[i];
347       if (i >= categoriesArray.length - 1) {
348         try {
349           subHash.put("leaf:" + obj.get("title"), obj.get("id"));
350         } catch (Exception e) {
351           System.err.println("JSON Exception: " + e.getMessage());
352         }
353       } else {
354         try {
355           subHash = (JSONObject) subHash.get("node:" + id);
356         } catch (Exception e) {
357           try {
358             JSONObject tmpHash = new JSONObject();
359             subHash.put("node:" + id, tmpHash);
360             subHash = tmpHash;
361           } catch (Exception ex) {
362             log.debug(ExceptionUtil.getStackTrace(e));
363           }
364         }
365       }
366     }
367     return hash;
368   }
369 
370   private boolean rename(String id, String desc) {
371     try {
372       File view = new File(path + "/views/" + id + ".view");
373       File newFile = new File(path + File.separator + "views" + File.separator
374           + desc + ".view");
375       if(!view.renameTo(newFile)) {
376         log.warn("Can not rename " + path + "/views/" + id + ".view to " + 
377             path + File.separator + "views" + File.separator + desc + ".view");
378       }
379     } catch (Exception e) {
380       return false;
381     }
382     return true;
383   }
384 
385 }