View Javadoc
1   /******************************************************************************
2    * PicBrowserAjaxController.java - The Spring controller for the PicMan AJAX calls
3    * 
4    * PicMan - The BuckoSoft Picture Manager in Java
5    * Copyright(c) 2009 - Dick Balaska
6    * 
7    */
8   package com.buckosoft.PicMan.web;
9   
10  import java.io.IOException;
11  import java.io.OutputStream;
12  import java.io.UnsupportedEncodingException;
13  import java.text.DecimalFormat;
14  import java.util.ArrayList;
15  import java.util.List;
16  
17  import javax.servlet.http.HttpServletRequest;
18  import javax.servlet.http.HttpServletResponse;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.dom4j.Document;
23  import org.dom4j.io.OutputFormat;
24  import org.dom4j.io.XMLWriter;
25  import org.springframework.web.servlet.ModelAndView;
26  
27  import com.buckosoft.BSAccount.web.BSAccountPageController;
28  import com.buckosoft.BSAccount.web.BSAccountUserWebSession;
29  import com.buckosoft.PicMan.business.PicManFacade;
30  import com.buckosoft.PicMan.dom.PicBrowserDom;
31  import com.buckosoft.PicMan.domain.MetaSet;
32  import com.buckosoft.PicMan.domain.MetaSetRule;
33  import com.buckosoft.PicMan.domain.User;
34  
35  /** Spring controller that returns DOMs for the PicMan PicBrowser.
36   * @author Dick Balaska
37   * @since 2009/06/15
38   * @see <a href="http://cvs.buckosoft.com/Projects/java/PicMan/PicMan/src/main/java/com/buckosoft/PicMan/web/PicBrowserAjaxController.java">PicBrowserAjaxController.java</a>
39   */
40  public class PicBrowserAjaxController extends BSAccountPageController {
41  	private static boolean DEBUG = true;
42  	protected final Log logger = LogFactory.getLog(getClass());
43  
44  	private PicManFacade pmf;
45  
46  	/** Set the reference to the PicMan API.
47  	 * @param pmf The PicManFacade
48  	 */
49  	public void setPicMan(PicManFacade pmf) { this.pmf = pmf; }
50  
51  	/** Enable debug logger output on this module
52  	 * @param debugFlag true == turn on debugging.
53  	 */
54  	public void setDEBUG(boolean debugFlag) {
55  		DEBUG = debugFlag;
56  	}
57  
58  	private	String 			cachedDeclaration = "";
59  	private	MetaSet			cachedMetaSet;
60  	private	PicNameWithLabel[]		cachedPics;
61  	private	int				cachedOffset = 0;
62  
63  	private final DecimalFormat df = new DecimalFormat("0.##");
64  
65  	public class PicNameWithLabel implements Comparable<PicNameWithLabel> {
66  		public String	name;
67  		public String	label;
68  		/* (non-Javadoc)
69  		 * @see java.lang.Comparable#compareTo(java.lang.Object)
70  		 */
71  		@Override
72  		public int compareTo(PicNameWithLabel o) {
73  			return(this.name.compareTo(o.name));
74  		}
75  		
76  	}
77  
78  	
79  	/** Spring standard http request handler.
80  	 * @param request The http request.
81  	 * @param response The http response.
82  	 * @return null to return just an http status because we pushed the DOM out the response.
83  	 */ 
84  	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
85  		String query = request.getQueryString();
86  		if (DEBUG) {
87  			//String sid = request.getParameter("sid");
88  				logger.info("Browser Request Q=" + query);
89  		}
90  
91  		User user = null;
92  		BSAccountUserWebSession userWebSession = this.bsAccountMan.getUserWebSession(request);
93  		if (userWebSession != null) 
94  			user = (User)userWebSession.getUser();
95  
96  		response.setContentType("text/xml");
97  		response.addHeader("Cache-Control", "max-age=0");
98  		response.addHeader("Cache-Control", "no-cache");
99  		response.addHeader("expires", "0");
100 		response.addHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT");
101 		response.addHeader("Pragma", "no-cache");
102 
103 		String[] ss = query.split("&", 2);
104 		if (ss[0].startsWith("z=")) {
105 			cachedOffset = Integer.parseInt(ss[0].substring(2));
106 		}
107 		if (ss.length == 1) {
108 			cachedDeclaration = null;
109 			cachedMetaSet = null;
110 			cachedPics = null;
111 			
112 		} else if (!ss[1].equals(cachedDeclaration)) {
113 			cachedDeclaration = ss[1];
114 			cachedMetaSet = buildMetaSetFromQuery(cachedDeclaration);
115 			List<String>l = pmf.getDB().getPicNamesBySet(cachedMetaSet, 75, MetaSet.NONE, 0);
116 			ArrayList<PicNameWithLabel>lpr = new ArrayList<PicNameWithLabel>();
117 			for (String pn : l) {
118 				PicNameWithLabel pnwr = new PicNameWithLabel();
119 				pnwr.name = pn;
120 				lpr.add(pnwr);
121 			}
122 			
123 			cachedPics = lpr.toArray(new PicNameWithLabel[0]);
124 			java.util.Arrays.sort(cachedPics);
125 //			for (int i=0; i<user.getPicBrowserPicsPerPage(); i++)
126 //				cachedPics[i].label = df.format(pmf.getDB().getPicRate(cachedPics[i].name, cachedMetaSet, 75));
127 		}
128 		
129 		Document dom = null;
130 		if (cachedPics != null && user.isPicBrowserShowRatings()) {
131 			int end = user.getPicBrowserPicsPerPage()+cachedOffset < cachedPics.length ? user.getPicBrowserPicsPerPage()+cachedOffset : cachedPics.length;
132 			for (int i=cachedOffset; i<end; i++)
133 				if (cachedPics[i].label == null)
134 					cachedPics[i].label = df.format(pmf.getDB().getPicRate(cachedPics[i].name, cachedMetaSet, 75));
135 		}
136 		dom = PicBrowserDom.createDocument(pmf, user, cachedPics, cachedOffset);
137 		try {
138 			OutputStream stream = response.getOutputStream();
139 			OutputFormat outformat = OutputFormat.createPrettyPrint();
140 			outformat.setEncoding("ISO-8859-1");
141 			XMLWriter writer = new XMLWriter(stream, outformat);
142 			writer.write(dom);
143 			writer.flush();
144 			writer.close();
145 			stream.close();
146 		} catch (UnsupportedEncodingException e) {
147 			logger.info(e);
148 			pmf.addError(e);
149 		} catch (IOException e) {
150 			logger.info(e);
151 			pmf.addError(e);
152 		}
153 
154 		if (cachedPics != null && user.isPicBrowserShowRatings()) {
155 			int start = user.getPicBrowserPicsPerPage()+cachedOffset;
156 			int end = start+cachedOffset < cachedPics.length ? start+cachedOffset : cachedPics.length;
157 			for (int i=start; i<end; i++)
158 				if (cachedPics[i].label == null)
159 					cachedPics[i].label = df.format(pmf.getDB().getPicRate(cachedPics[i].name, cachedMetaSet, 75));
160 		}
161 		return null;
162 	}
163 	
164 	private MetaSet buildMetaSetFromQuery(String query) {
165 		MetaSet ms = new MetaSet();
166 		if (DEBUG)
167 			logger.info("buildFromQuery '" + query + "'");
168 		String[] ss = query.split("&");
169 		for (int i=0; i<ss.length; i++) {
170 			MetaSetRule rule;
171 			String[] pv = ss[i].split("=");
172 			char command = pv[0].charAt(0);
173 			int index = Integer.parseInt(pv[0].substring(1));
174 			int value = 0;
175 			try {
176 				value = Integer.parseInt(pv[1]);
177 			} catch (Exception e) {}
178 
179 			if (index >= ms.getRuleCount()) {
180 				rule = new MetaSetRule();
181 				rule.setIndex(index);
182 				ms.addRule(rule);
183 			} else {
184 				rule = ms.getRule(index);
185 			}
186 			if (command == 's') {
187 				if (value < 0) {
188 					rule.setType(MetaSet.FUNCTION);
189 					rule.setSid(value);
190 					rule.setRateVal(value);
191 				} else {
192 					rule.setType(MetaSet.NAME);
193 					rule.setSid(value);
194 					rule.setValue(pmf.getDB().getSet(value).getName());
195 				}
196 			}
197 			if (command == 'r') {
198 				rule.setType(MetaSet.OPERATOR);
199 				rule.setOperator(value);
200 			}
201 			if (command == 'q')
202 				rule.setRateOp(value);
203 			if (command == 'v' && rule.getType() != MetaSet.FUNCTION)
204 				rule.setRateVal(value);
205 		}
206 		return(ms);
207 	}
208 }