001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.ui.progress; 020 021import java.io.IOException; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025import java.util.UUID; 026 027import javax.servlet.ServletException; 028import javax.servlet.http.HttpServletRequest; 029import javax.servlet.http.HttpServletResponse; 030 031import org.apache.log4j.Logger; 032import org.apache.wiki.ajax.WikiAjaxDispatcherServlet; 033import org.apache.wiki.ajax.WikiAjaxServlet; 034 035/** 036 * Manages progressing items. In general this class is used whenever JSPWiki 037 * is doing something which may require a long time. In addition, this manager 038 * provides a JSON interface for finding remotely what the progress is. The 039 * JSON object name is JSON_PROGRESSTRACKER = "{@value #JSON_PROGRESSTRACKER}". 040 * 041 * @since 2.6 042 */ 043// FIXME: Needs synchronization, I think 044public class ProgressManager 045{ 046 private Map<String,ProgressItem> m_progressingTasks = new HashMap<String,ProgressItem>(); 047 048 /** 049 * The name of the progress tracker JSON object. The current value is "{@value}", 050 */ 051 public static final String JSON_PROGRESSTRACKER = "progressTracker"; 052 053 private static Logger log = Logger.getLogger( ProgressManager.class ); 054 055 /** 056 * Creates a new ProgressManager. 057 */ 058 public ProgressManager() 059 { 060 //TODO: Replace with custom annotations. See JSPWIKI-566 061 WikiAjaxDispatcherServlet.registerServlet( JSON_PROGRESSTRACKER, new JSONTracker() ); 062 } 063 064 /** 065 * You can use this to get an unique process identifier. 066 * @return A new random value 067 */ 068 public String getNewProgressIdentifier() 069 { 070 return UUID.randomUUID().toString(); 071 } 072 073 /** 074 * Call this method to get your ProgressItem into the ProgressManager queue. 075 * The ProgressItem will be moved to state STARTED. 076 * 077 * @param pi ProgressItem to start 078 * @param id The progress identifier 079 */ 080 public void startProgress( ProgressItem pi, String id ) 081 { 082 log.debug("Adding "+id+" to progress queue"); 083 m_progressingTasks.put( id, pi ); 084 pi.setState( ProgressItem.STARTED ); 085 } 086 087 /** 088 * Call this method to remove your ProgressItem from the queue (after which 089 * getProgress() will no longer find it. The ProgressItem will be moved to state 090 * STOPPED. 091 * 092 * @param id The progress identifier 093 */ 094 public void stopProgress( String id ) 095 { 096 log.debug("Removed "+id+" from progress queue"); 097 ProgressItem pi = m_progressingTasks.remove( id ); 098 if( pi != null ) pi.setState( ProgressItem.STOPPED ); 099 } 100 101 /** 102 * Get the progress in percents. 103 * 104 * @param id The progress identifier. 105 * @return a value between 0 to 100 indicating the progress 106 * @throws IllegalArgumentException If no such progress item exists. 107 */ 108 public int getProgress( String id ) 109 throws IllegalArgumentException 110 { 111 ProgressItem pi = m_progressingTasks.get( id ); 112 113 if( pi != null ) 114 { 115 return pi.getProgress(); 116 } 117 118 throw new IllegalArgumentException("No such id was found"); 119 } 120 121 /** 122 * Provides access to a progress indicator, assuming you know the ID. 123 * Progress of zero (0) means that the progress has just started, and a progress of 124 * 100 means that it is complete. 125 */ 126 public class JSONTracker implements WikiAjaxServlet 127 { 128 /** 129 * Returns upload progress in percents so far. 130 * @param progressId The string representation of the progress ID that you want to know the 131 * progress of. 132 * @return a value between 0 to 100 indicating the progress 133 */ 134 public int getProgress( String progressId ) 135 { 136 return ProgressManager.this.getProgress( progressId ); 137 } 138 139 public String getServletMapping() { 140 return JSON_PROGRESSTRACKER; 141 } 142 143 public void service(HttpServletRequest req, HttpServletResponse resp, String actionName, List<String> params) 144 throws ServletException, IOException 145 { 146 log.debug("ProgressManager.doGet() START"); 147 if (params.size()<1) { 148 return; 149 } 150 String progressId = params.get(0); 151 log.debug("progressId="+progressId); 152 String progressString = ""; 153 try { 154 int progress = getProgress(progressId); 155 progressString = Integer.toString(progress); 156 } catch (IllegalArgumentException e) { 157 // ignore 158 log.debug("progressId "+progressId+" is no longer valid"); 159 } 160 log.debug("progressString="+progressString); 161 resp.getWriter().write(progressString); 162 log.debug("ProgressManager.doGet() DONE"); 163 } 164 } 165}