Java tutorial
/* * Licensed 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.wookie.controller; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; import org.apache.wookie.Messages; import org.apache.wookie.beans.IAccessLog; import org.apache.wookie.beans.IApiKey; import org.apache.wookie.beans.IApikeyWidget; import org.apache.wookie.beans.ISharedData; import org.apache.wookie.beans.IStartFile; import org.apache.wookie.beans.IWidget; import org.apache.wookie.beans.IWidgetInstance; import org.apache.wookie.beans.jpa.impl.AccessLogImpl; import org.apache.wookie.beans.util.IPersistenceManager; import org.apache.wookie.beans.util.PersistenceManagerFactory; import org.apache.wookie.exceptions.InvalidWidgetCallException; import org.apache.wookie.helpers.Notifier; import org.apache.wookie.helpers.WidgetInstanceFactory; import org.apache.wookie.helpers.WidgetInstanceHelper; import org.apache.wookie.helpers.WidgetKeyManager; import org.apache.wookie.server.LocaleHandler; import org.apache.wookie.w3c.util.LocalizationUtils; /** * REST implementation for widgetInstance * * POST: creates and returns (or just returns) an instance PUT: stop, resume, or * clone an instance (GET: redirect to other actions. Useful for some limited * clients) * */ public class WidgetInstancesController extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { private static final long serialVersionUID = 308590474406800659L; static Logger _logger = Logger.getLogger(WidgetInstancesController.class.getName()); protected static final String CONTENT_TYPE = "text/xml;charset=\"UTF-8\""; //$NON-NLS-1$ protected static URL urlWidgetProxyServer = null; public static String checkProxy(HttpServletRequest request) { // set the proxy url. if (urlWidgetProxyServer == null) { Configuration properties = (Configuration) request.getSession().getServletContext() .getAttribute("properties"); //$NON-NLS-1$ String scheme = request.getScheme(); String serverName = request.getServerName(); int serverPort = request.getServerPort(); if (!properties.getString("widget.proxy.scheme").trim().equals("")) //$NON-NLS-1$//$NON-NLS-2$ scheme = properties.getString("widget.proxy.scheme"); //$NON-NLS-1$ if (!properties.getString("widget.proxy.hostname").trim().equals("")) //$NON-NLS-1$//$NON-NLS-2$ serverName = properties.getString("widget.proxy.hostname"); //$NON-NLS-1$ if (!properties.getString("widget.proxy.port").trim().equals("")) //$NON-NLS-1$//$NON-NLS-2$ serverPort = Integer.parseInt(properties.getString("widget.proxy.port")); //$NON-NLS-1$ try { urlWidgetProxyServer = new URL(scheme, serverName, serverPort, properties.getString("widget.proxy.path")); } catch (MalformedURLException e) { // ignore errors } } return urlWidgetProxyServer.toExternalForm(); } /* * (non-Javadoc) * * @see * javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest * , javax.servlet.http.HttpServletResponse) */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!WidgetKeyManager.isValidRequest(request)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } else { doGetWidget(request, response); } } /* * (non-Javadoc) * * @see * javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest * , javax.servlet.http.HttpServletResponse) */ @Override protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!WidgetKeyManager.isValidRequest(request)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } else { try { String requestId = request.getParameter("requestid"); //$NON-NLS-1$ if (requestId == null || requestId.equals("")) { response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } else { if (requestId.equals("stopwidget")) { //$NON-NLS-1$ doStopWidget(request, response); } else if (requestId.equals("resumewidget")) { //$NON-NLS-1$ doResumeWidget(request, response); } else if (requestId.equals("clone")) { //$NON-NLS-1$ cloneSharedData(request, response); } else { response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } } } catch (Exception ex) { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } } /* * (non-Java-doc) * * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, * HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) { if (!WidgetKeyManager.isValidRequest(request)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } else { try { String requestId = request.getParameter("requestid"); //$NON-NLS-1$ if (requestId == null || requestId.equals("")) { response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } else { if (requestId.equals("getwidget")) { //$NON-NLS-1$ doGetWidget(request, response); } else if (requestId.equals("stopwidget")) { //$NON-NLS-1$ doStopWidget(request, response); } else if (requestId.equals("resumewidget")) { //$NON-NLS-1$ doResumeWidget(request, response); } else if (requestId.equals("clone")) { //$NON-NLS-1$ cloneSharedData(request, response); } else { response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } } } catch (Exception ex) { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } } // / Implementation public static void doStopWidget(HttpServletRequest request, HttpServletResponse response) throws IOException { Messages localizedMessages = LocaleHandler.localizeMessages(request); IWidgetInstance instance = WidgetInstancesController.findWidgetInstance(request); if (instance != null) { lockWidgetInstance(instance); Notifier.notifyWidgets(request.getSession(), instance, Notifier.STATE_UPDATED); response.setStatus(HttpServletResponse.SC_OK); } else { response.sendError(HttpServletResponse.SC_BAD_REQUEST, localizedMessages.getString("WidgetServiceServlet.3"));//$NON-NLS-1$ } } public static void doResumeWidget(HttpServletRequest request, HttpServletResponse response) throws IOException { Messages localizedMessages = LocaleHandler.localizeMessages(request); IWidgetInstance instance = WidgetInstancesController.findWidgetInstance(request); if (instance != null) { unlockWidgetInstance(instance); Notifier.notifyWidgets(request.getSession(), instance, Notifier.STATE_UPDATED); response.setStatus(HttpServletResponse.SC_OK); } else { response.sendError(HttpServletResponse.SC_BAD_REQUEST, localizedMessages.getString("WidgetServiceServlet.3"));//$NON-NLS-1$ } } public static void doGetWidget(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // System.out.println("doGetWidget() in WidgetInstancesController"); String userId = request.getParameter("userid"); //$NON-NLS-1$ // System.out.println("userid="+userId); String sharedDataKey = getSharedDataKey(request); // System.out.println("sharedDataKey="+sharedDataKey); String serviceType = request.getParameter("servicetype"); //$NON-NLS-1$ // System.out.println("serviceType="+serviceType); String widgetId = request.getParameter("widgetid"); //$NON-NLS-1$ // System.out.println("widgetid="+widgetId); HttpSession session = request.getSession(true); Messages localizedMessages = LocaleHandler.localizeMessages(request); try { if (userId == null || sharedDataKey == null || (serviceType == null && widgetId == null)) { throw new InvalidWidgetCallException(); } } catch (InvalidWidgetCallException ex) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } checkProxy(request); // check if this API_KEY is allowed to instanciate this widget String apiKey = request.getParameter("api_key"); //$NON-NLS-1$ IPersistenceManager persistenceManager = PersistenceManagerFactory.getPersistenceManager(); IWidget iw = persistenceManager.findWidgetByGuid(widgetId); Integer wid = new Integer(iw.getId().toString()); IApiKey[] akey = persistenceManager.findByValue(IApiKey.class, "value", apiKey); int storeUserid = 0; int apikeyId = 0; if (akey != null && akey.length != 0) { storeUserid = akey[0].getUserId(); apikeyId = new Integer(akey[0].getId().toString()); } IApikeyWidget[] akeyWid = persistenceManager.findByValue(IApikeyWidget.class, "apiKey", apikeyId); boolean allowed = false; if (akeyWid != null && akeyWid.length != 0) { if (akeyWid[0].getWidgetId() == 0) {// 0 means access to ALL widgets allowed = true; } else { for (int j = 0; j < akeyWid.length; j++) { if (akeyWid[j].getWidgetId() == wid) { allowed = true; break; } } } } try { if (!allowed) { throw new InvalidWidgetCallException( "Api_key:" + apiKey + " is not allowed to instanciate widget " + widgetId); } } catch (InvalidWidgetCallException ex) { System.out.println("WidgetInstancesController exception"); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } System.out.println("before logging"); // Log this request on db AccessLogImpl al = new AccessLogImpl(wid, storeUserid, apikeyId, userId); persistenceManager.save(al); //AccessLogImpl al = persistenceManager.newInstance(AccessLogImpl.class); //al.setWidgetId(wid); //al.setContainerUser(userId); //al.setApiKeyId(apikeyId); //al.setUserId(storeUserid); //persistenceManager.save(al); System.out.println("after logging"); IWidgetInstance instance = WidgetInstancesController.findWidgetInstance(request); String locale = request.getParameter("locale");//$NON-NLS-1$ // Widget exists if (instance == null) { instance = WidgetInstanceFactory.getWidgetFactory(session, localizedMessages).newInstance(apiKey, userId, sharedDataKey, serviceType, widgetId, locale); response.setStatus(HttpServletResponse.SC_CREATED); } else { // If the requested locale is different to the saved locale, update // the "lang" attribute // of the widget instance and save it if ((locale == null && instance.getLang() != null) || (locale != null && instance.getLang() == null) || (locale != null && !instance.getLang().equals(locale))) { instance.setLang(locale); persistenceManager.save(instance); } response.setStatus(HttpServletResponse.SC_OK); } // Return the default widget if not created by now if (instance == null) { instance = WidgetInstanceFactory.defaultInstance(locale); response.setStatus(HttpServletResponse.SC_NOT_FOUND); } String url = getUrl(request, instance); response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); out.println(WidgetInstanceHelper.createXMLWidgetInstanceDocument(instance, url)); } public static void cloneSharedData(HttpServletRequest request, HttpServletResponse response) { IWidgetInstance instance = WidgetInstancesController.findWidgetInstance(request); if (instance == null) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } String sharedDataKey = getSharedDataKey(request); String cloneSharedDataKey = request.getParameter("cloneshareddatakey"); if (sharedDataKey == null || sharedDataKey.trim().equals("") || cloneSharedDataKey == null //$NON-NLS-1$ || cloneSharedDataKey.trim().equals("")) {//$NON-NLS-1$ response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return; } String cloneKey = String.valueOf((request.getParameter("apikey") + ":" + cloneSharedDataKey).hashCode());//$NON-NLS-1$ IWidget widget = instance.getWidget(); IPersistenceManager persistenceManager = PersistenceManagerFactory.getPersistenceManager(); for (ISharedData sharedData : widget.getSharedData(sharedDataKey)) { ISharedData clone = persistenceManager.newInstance(ISharedData.class); clone.setDkey(sharedData.getDkey()); clone.setDvalue(sharedData.getDvalue()); clone.setSharedDataKey(cloneKey); widget.getSharedData().add(clone); } boolean ok = persistenceManager.save(widget); if (ok) { response.setStatus(HttpServletResponse.SC_OK); } else { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } public synchronized static void lockWidgetInstance(IWidgetInstance instance) { // doLock(instance, true); PropertiesController.updateSharedDataEntry(instance, "isLocked", "true", false);//$NON-NLS-1$ //$NON-NLS-2$ instance.setLocked(true); IPersistenceManager persistenceManager = PersistenceManagerFactory.getPersistenceManager(); persistenceManager.save(instance); } public synchronized static void unlockWidgetInstance(IWidgetInstance instance) { // doLock(instance, false); PropertiesController.updateSharedDataEntry(instance, "isLocked", "false", false);//$NON-NLS-1$ //$NON-NLS-2$ instance.setLocked(false); IPersistenceManager persistenceManager = PersistenceManagerFactory.getPersistenceManager(); persistenceManager.save(instance); } // Utility methods /** * Returns the internal form of shared data key, which is hashed along with * the API key. This prevents shared data keys from clashing between * different applications * * @param request * the HTTP request to retrieve the shared data key from * @return the shared data key */ public static String getSharedDataKey(HttpServletRequest request) { return String .valueOf((request.getParameter("apikey") + ":" + request.getParameter("shareddatakey")).hashCode()); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Returns the absolute URL of the widget instance including id key, proxy * url and opensocial token * * @param request * the current request * @param instance * the widget instance * @return the absolute URL * @throws IOException */ protected static String getUrl(HttpServletRequest request, IWidgetInstance instance) throws IOException { String url = ""; IStartFile[] startFiles = instance.getWidget().getStartFiles() .toArray(new IStartFile[instance.getWidget().getStartFiles().size()]); IStartFile sf = (IStartFile) LocalizationUtils.getLocalizedElement(startFiles, new String[] { instance.getLang() }); // Try default locale if no appropriate localization found if (sf == null) sf = (IStartFile) LocalizationUtils.getLocalizedElement(startFiles, null); // No start file found, so throw an exception if (sf == null) throw new IOException("No start file located for widget " + instance.getWidget().getGuid()); URL urlWidget = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), sf.getUrl()); if (urlWidget.getQuery() != null) { url += urlWidget + "&idkey=" + instance.getIdKey() //$NON-NLS-1$ + "&proxy=" + urlWidgetProxyServer.toExternalForm() //$NON-NLS-1$ + "&st=" + instance.getOpensocialToken(); //$NON-NLS-1$ } else { url += urlWidget + "?idkey=" + instance.getIdKey() //$NON-NLS-1$ + "&proxy=" + urlWidgetProxyServer.toExternalForm() //$NON-NLS-1$ + "&st=" + instance.getOpensocialToken(); //$NON-NLS-1$ } return url; } /** * Utility method for locating an instance based on various parameters. * Consider moving to a utils class, or even to the WidgetInstance * ActiveRecord class. * * @param request * @return */ public static IWidgetInstance findWidgetInstance(HttpServletRequest request) { IWidgetInstance instance; IPersistenceManager persistenceManager = PersistenceManagerFactory.getPersistenceManager(); String id_key = request.getParameter("id_key"); //$NON-NLS-1$ if (id_key != null & id_key != "") { instance = persistenceManager.findWidgetInstanceByIdKey(id_key); return instance; } try { String apiKey = URLDecoder.decode(request.getParameter("api_key"), "UTF-8"); //$NON-NLS-1$ String userId = URLDecoder.decode(request.getParameter("userid"), "UTF-8"); //$NON-NLS-1$ String sharedDataKey = WidgetInstancesController.getSharedDataKey(request); String widgetId = request.getParameter("widgetid"); if (widgetId != null) { widgetId = URLDecoder.decode(widgetId, "UTF-8"); //$NON-NLS-1$ _logger.debug("Looking for widget instance with widgetid of " + widgetId); instance = persistenceManager.findWidgetInstanceByGuid(apiKey, userId, sharedDataKey, widgetId); } else { String serviceType = URLDecoder.decode(request.getParameter("servicetype"), "UTF-8"); //$NON-NLS-1$ _logger.debug("Looking for widget instance of service type " + serviceType); instance = persistenceManager.findWidgetInstance(apiKey, userId, sharedDataKey, serviceType); } if (instance == null) { _logger.debug("No widget instance found for APIkey= " + apiKey + " userId=" + userId + " widgetId=" + widgetId); } return instance; } catch (UnsupportedEncodingException e) { throw new RuntimeException("Server must support UTF-8 encoding", e); } //$NON-NLS-1$ } }