Author: scottbw
Date: Wed Nov 25 23:31:16 2009
New Revision: 884338

URL: http://svn.apache.org/viewvc?rev=884338&view=rev
Log:
Implemented a watched folder solution for WOOKIE-51 that allows hot deployment 
of widgets by dropping in .wgt files. This also involved separating further the 
WidgetPackageUtils methods from the servlet concerns, and pushing more widget 
package processing out of the admin servlet.

Added:
    incubator/wookie/trunk/WebContent/deploy/
    incubator/wookie/trunk/src/org/apache/wookie/util/WgtWatcher.java
Modified:
    incubator/wookie/trunk/src/org/apache/wookie/WidgetAdminServlet.java
    incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java
    incubator/wookie/trunk/src/org/apache/wookie/util/WidgetPackageUtils.java
    incubator/wookie/trunk/src/widgetserver.properties

Modified: incubator/wookie/trunk/src/org/apache/wookie/WidgetAdminServlet.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/WidgetAdminServlet.java?rev=884338&r1=884337&r2=884338&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/WidgetAdminServlet.java 
(original)
+++ incubator/wookie/trunk/src/org/apache/wookie/WidgetAdminServlet.java Wed 
Nov 25 23:31:16 2009
@@ -27,7 +27,6 @@
 import javax.servlet.http.HttpSession;
 
 import org.apache.commons.configuration.Configuration;
-import org.apache.commons.compress.archivers.zip.ZipFile;
 import org.apache.log4j.Logger;
 import org.apache.wookie.beans.ApiKey;
 import org.apache.wookie.beans.Whitelist;
@@ -42,13 +41,9 @@
 import org.apache.wookie.manager.IWidgetAdminManager;
 import org.apache.wookie.manager.impl.WidgetAdminManager;
 import org.apache.wookie.manifestmodel.IManifestModel;
-import org.apache.wookie.manifestmodel.impl.ContentEntity;
-import org.apache.wookie.manifestmodel.impl.WidgetManifestModel;
 import org.apache.wookie.server.LocaleHandler;
-import org.apache.wookie.util.StartPageJSParser;
 import org.apache.wookie.util.WidgetPackageUtils;
 import org.apache.wookie.util.gadgets.GadgetUtils;
-import org.jdom.JDOMException;
 
 /**
  * Servlet implementation class for Servlet: WidgetAdminServlet
@@ -361,11 +356,12 @@
        }
 
        private void removeWidget(HttpSession session, HttpServletRequest 
request, Configuration properties, IWidgetAdminManager manager) {
+               final String WIDGETFOLDER = 
request.getSession().getServletContext().getRealPath(properties.getString("widget.widgetfolder"));//$NON-NLS-1$
                Messages localizedMessages = 
LocaleHandler.localizeMessages(request);
                String widgetId = request.getParameter("widgetId"); 
//$NON-NLS-1$
                String guid = manager.getWidgetGuid(Integer.parseInt(widgetId));
                
if(manager.removeWidgetAndReferences(Integer.parseInt(widgetId))){
-                       if(WidgetPackageUtils.removeWidgetResources(request, 
properties, guid)){                        
+                       
if(WidgetPackageUtils.removeWidgetResources(WIDGETFOLDER, guid)){               
        
                                session.setAttribute("message_value", 
localizedMessages.getString("WidgetAdminServlet.12"));                     
//$NON-NLS-1$ //$NON-NLS-2$ 
                        }
                        else{
@@ -449,12 +445,16 @@
        }
 
        private void uploadOperation(HttpServletRequest request, Configuration 
properties, IWidgetAdminManager manager, HttpSession session) {
+
+               final String WIDGETFOLDER = 
request.getSession().getServletContext().getRealPath(properties.getString("widget.widgetfolder"));//$NON-NLS-1$
+               final String UPLOADFOLDER = 
request.getSession().getServletContext().getRealPath(properties.getString("widget.useruploadfolder"));//$NON-NLS-1$
+               
                Messages localizedMessages = 
LocaleHandler.localizeMessages(request);
                session.setAttribute("hasValidated", Boolean.valueOf(false)); 
//$NON-NLS-1$
                session.setAttribute("closeWindow", Boolean.valueOf(true)); 
//$NON-NLS-1$
                File zipFile;
                try {
-                       zipFile = 
WidgetPackageUtils.dealWithUploadFile(request, properties);
+                       zipFile = 
WidgetPackageUtils.dealWithUploadFile(UPLOADFOLDER, request);
                } 
                catch (Exception ex) {
                        session.setAttribute("error_value", 
localizedMessages.getString("WidgetAdminServlet.28") + "\n" + ex.getMessage()); 
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@@ -463,69 +463,30 @@
 
                try {   
                        if(zipFile.exists()){
-                               ZipFile zip = new ZipFile(zipFile);
-                               if (WidgetPackageUtils.hasManifest(zip)){
-                                       // build the model
-                                       IManifestModel widgetModel = new 
WidgetManifestModel(WidgetPackageUtils.extractManifest(zip), zip);              
                                                                                
                       
-
-                                       // get the start file; if there is no 
valid start file an exception will be thrown
-                                       String src = 
WidgetPackageUtils.locateStartFile(widgetModel, zip);
-                                       // get the widget identifier
-                                       String manifestIdentifier = 
widgetModel.getIdentifier();                                                
-                                       // create the folder structure to unzip 
the zip into
-                                       File newWidgetFolder = 
WidgetPackageUtils.createUnpackedWidgetFolder(request, properties, 
manifestIdentifier);
-                                       // now unzip it into that folder
-                                       WidgetPackageUtils.unpackZip(zip, 
newWidgetFolder);                                                     
-                                       // get the url to the start page
-                                       String relativestartUrl = 
(WidgetPackageUtils.getURLForWidget(properties, manifestIdentifier, src));
-                                       // update the model version of the 
start page (or create one if none exists)
-                                       if (widgetModel.getContent() == null) 
widgetModel.setContent(new ContentEntity()); 
-                                       
widgetModel.getContent().setSrc(relativestartUrl);
-                                       // now update the js links in the start 
page
-                                       File startFile = new 
File(newWidgetFolder.getCanonicalPath() + File.separator + src);                
                                   
-                                       if(startFile.exists()){                 
                                        
-                                               StartPageJSParser parser = new 
StartPageJSParser(startFile, widgetModel);
-                                               parser.doParse();
-                                       }                                       
                
-                                       // get the path to the root of the 
unzipped folder
-                                       String localPath = 
WidgetPackageUtils.getURLForWidget(properties, manifestIdentifier, "");
-                                       // now pass this to the model which 
will prepend the path to local resources (not web icons)
-                                       widgetModel.updateIconPaths(localPath); 
                                                
-                                       // check to see if this widget already 
exists in the DB - using the ID (guid) key from the manifest
-                                       
if(!manager.doesWidgetAlreadyExistInSystem(manifestIdentifier)){                
                                                        
-                                               int dbkey = 
manager.addNewWidget(widgetModel, new String[]{});
-                                               // widget added
-                                               
session.setAttribute("message_value", "'"+ widgetModel.getLocalName("en") +"' - 
" + localizedMessages.getString("WidgetAdminServlet.19")); //$NON-NLS-1$ 
//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-                                               retrieveServices(session, 
manager);
-                                               
session.setAttribute("hasValidated", Boolean.valueOf(true));                    
                                                                                
                                 //$NON-NLS-1$
-                                               session.setAttribute("dbkey", 
dbkey); //$NON-NLS-1$
-                                               boolean isMaxable = 
manager.isWidgetMaximized(dbkey);
-                                               
session.setAttribute("isMaxable", Boolean.valueOf(isMaxable)); //$NON-NLS-1$
-                                       }       
-                                       else{
-                                               // TODO - call the manager to 
update required resources
-                                               // widget updated
-                                               
session.setAttribute("message_value", "'"+ widgetModel.getLocalName("en") +"' - 
" + localizedMessages.getString("WidgetAdminServlet.20")); //$NON-NLS-1$ 
//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-                                       }                                       
        
-                               }
+                               IManifestModel widgetModel = 
WidgetPackageUtils.processWidgetPackage(zipFile,properties.getString("widget.widgetfolder"),
 WIDGETFOLDER,UPLOADFOLDER);//$NON-NLS-1$
+                               
if(!manager.doesWidgetAlreadyExistInSystem(widgetModel.getIdentifier())){       
+                                       // ADD
+                                       int dbkey = 
manager.addNewWidget(widgetModel, new String[]{});
+                                       // widget added
+                                       session.setAttribute("message_value", 
"'"+ widgetModel.getLocalName("en") +"' - " + 
localizedMessages.getString("WidgetAdminServlet.19")); //$NON-NLS-1$ 
//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                                       retrieveServices(session, manager);
+                                       session.setAttribute("hasValidated", 
Boolean.valueOf(true));                                                         
                                                                            
//$NON-NLS-1$
+                                       session.setAttribute("dbkey", dbkey); 
//$NON-NLS-1$
+                                       boolean isMaxable = 
manager.isWidgetMaximized(dbkey);
+                                       session.setAttribute("isMaxable", 
Boolean.valueOf(isMaxable)); //$NON-NLS-1$
+                               }       
                                else{
-                                       // no manifest file found in zip archive
-                                       throw new 
BadWidgetZipFileException(localizedMessages.getString("WidgetAdminServlet.23"));
 //$NON-NLS-1$ 
-                               }
+                                       // UPDATE
+                                       // TODO - call the manager to update 
required resources
+                                       // widget updated
+                                       session.setAttribute("message_value", 
"'"+ widgetModel.getLocalName("en") +"' - " + 
localizedMessages.getString("WidgetAdminServlet.20")); //$NON-NLS-1$ 
//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                               }                                       
                        }
                        else{
                                // no file found to be uploaded - shouldn't 
happen
                                session.setAttribute("error_value", 
localizedMessages.getString("WidgetAdminServlet.24")); //$NON-NLS-1$ 
//$NON-NLS-2$
                        }                                               
                }                
-               catch (JDOMException ex) {
-                       _logger.error(ex);                      
-                       session.setAttribute("error_value", 
localizedMessages.getString("WidgetAdminServlet.25") + "\n" + ex.getMessage()); 
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-               }
-               catch (IOException ex) {
-                       _logger.error(ex);
-                       session.setAttribute("error_value", 
localizedMessages.getString("WidgetAdminServlet.25") + "\n" + ex.getMessage()); 
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-               }       
                catch (InvalidStartFileException ex){
                        _logger.error(ex);
                        session.setAttribute("error_value", 
localizedMessages.getString("WidgetAdminServlet.27") + "\n" + ex.getMessage()); 
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$                   
@@ -543,6 +504,10 @@
                        if (ex.getMessage() == null || 
ex.getMessage().equals("")) message = 
localizedMessages.getString("WidgetAdminServlet.29"); //$NON-NLS-1$
                        session.setAttribute("error_value", message); 
//$NON-NLS-1$
                }
+               catch (Exception ex) {
+                       _logger.error(ex);                      
+                       session.setAttribute("error_value", 
localizedMessages.getString("WidgetAdminServlet.25") + "\n" + ex.getMessage()); 
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+               }
 
 
        }

Modified: 
incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java?rev=884338&r1=884337&r2=884338&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java 
(original)
+++ incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java 
Wed Nov 25 23:31:16 2009
@@ -15,14 +15,23 @@
 package org.apache.wookie.server;
 
 
+import java.io.File;
+
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 import org.apache.log4j.Logger;
+import org.apache.wookie.manager.impl.WidgetAdminManager;
+import org.apache.wookie.manifestmodel.IManifestModel;
+import org.apache.wookie.util.WgtWatcher;
+import org.apache.wookie.util.WidgetPackageUtils;
+import org.apache.wookie.util.hibernate.DBManagerFactory;
 import org.apache.wookie.util.hibernate.HibernateUtil;
+import org.apache.wookie.util.hibernate.IDBManager;
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
+
 /**
  * ContextListener - does some init work and makes certain things are 
available 
  * to resources under this context
@@ -50,23 +59,106 @@
                         *  load the widgetserver.properties file and put it 
into this context
                         *  as an attribute 'properties' available to all 
resources
                         */
-                       Configuration configuration = new 
PropertiesConfiguration("widgetserver.properties");
+                       PropertiesConfiguration configuration;
+                       File localPropsFile = new 
File(System.getProperty("user.dir") + File.separator + 
"local.widgetserver.properties");
+                       if (localPropsFile.exists()) {
+                               configuration = new 
PropertiesConfiguration(localPropsFile);
+                               _logger.info("Using local widget server 
properties file: " + localPropsFile.toString());
+                       } else {
+                               configuration = new 
PropertiesConfiguration("widgetserver.properties");
+                               configuration.setFile(localPropsFile);
+                               configuration.save();
+                               _logger.info("Using default widget server 
properties, configure your local server using: " + localPropsFile.toString());
+                       }
                        context.setAttribute("properties", (Configuration) 
configuration);
-                       /* 
-                        *  load the opensocial.properties file and put it into 
this context
-                        *  as an attribute 'opensocial' available to all 
resources
-                        */
-                       Configuration opensocialConfiguration = new 
PropertiesConfiguration("opensocial.properties");
-                       context.setAttribute("opensocial", (Configuration) 
opensocialConfiguration);
                        /*
                         * Initialise the locale handler
                         */
                        LocaleHandler.getInstance().initialize(configuration);
+       
+                       if (configuration.getBoolean("widget.hot_deploy")) 
startWatcher(context, configuration);
+                       
+                       /* 
+                        *  load the opensocial.properties file and put it into 
this context
+                        *  as an attribute 'opensocial' available to all 
resources
+                        */
+                       PropertiesConfiguration opensocialConfiguration;
+                       File localOpenSocialPropsFile = new 
File(System.getProperty("user.dir") + File.separator + 
"local.opensocial.properties");
+                       if (localOpenSocialPropsFile.exists()) {
+                               opensocialConfiguration = new 
PropertiesConfiguration(localOpenSocialPropsFile);
+                               _logger.info("Using local open social 
properties file: " + localOpenSocialPropsFile.toString());
+                       } else {
+                               opensocialConfiguration = new 
PropertiesConfiguration("opensocial.properties");
+                               
opensocialConfiguration.setFile(localOpenSocialPropsFile);
+                               opensocialConfiguration.save();
+                               _logger.info("Using default open social 
properties, configure your local server using: " + 
localOpenSocialPropsFile.toString());
+                       }
+                       context.setAttribute("opensocial", (Configuration) 
opensocialConfiguration);
                } 
                catch (ConfigurationException ex) {
                        _logger.error("ConfigurationException thrown: "+ 
ex.toString());
                }                                       
        }
+       
+       /**
+        * Starts a watcher thread for hot-deploy of new widgets dropped into 
the deploy folder
+        * this is controlled using the 
<code>widget.hot_deploy=true|false</code> property 
+        * and configured to look in the folder specified by the 
<code>widget.deployfolder</code> property
+        * @param context the current servlet context
+        * @param configuration the configuration properties
+        */
+       private void startWatcher(ServletContext context, Configuration 
configuration){
+               /*
+                * Start watching for widget deployment
+                */
+               final File deploy = new 
File(WidgetPackageUtils.convertPathToPlatform(context.getRealPath(configuration.getString("widget.deployfolder"))));
+               final String UPLOADFOLDER = 
context.getRealPath(configuration.getString("widget.useruploadfolder"));
+               final String WIDGETFOLDER = 
context.getRealPath(configuration.getString("widget.widgetfolder"));
+               final String localWidgetFolderPath = 
configuration.getString("widget.widgetfolder");
+               Thread thr = new Thread(){
+                       public void run() {
+                               /** Get a DBManager for this thread. */
+                               final IDBManager dbManager = 
DBManagerFactory.getDBManager();
+                               int interval = 5000;
+                               WgtWatcher watcher = new WgtWatcher();
+                               watcher.setWatchDir(deploy);
+                               watcher.setListener(new 
WgtWatcher.FileChangeListener(){
+                                       public void fileModified(File f) {
+                                               _logger.info("Deploying 
widget:"+f.getName());
+                                               try {
+                                                       try {                   
+                                                               
dbManager.beginTransaction();
+                                                               File upload = 
WidgetPackageUtils.dealWithDroppedFile(UPLOADFOLDER, f);
+                                                               IManifestModel 
model = WidgetPackageUtils.processWidgetPackage(upload, localWidgetFolderPath, 
WIDGETFOLDER, UPLOADFOLDER);
+                                                               
WidgetAdminManager manager = new WidgetAdminManager(null);
+                                                               
manager.addNewWidget(model, null);      
+                                                               
dbManager.commitTransaction();
+                                                       }
+                                                       catch (Exception e) {
+                                                               
_logger.error("error: " + e.getCause());
+                                                       }
+                                               } catch (Exception e) {
+                                                       _logger.error("error: 
"+e.getCause());
+                                               }
+                                       }
+                                       public void fileRemoved(File f) {
+                                               // Not implemented - the .wgt 
files are removed as part of the deployment process
+                                       }
+                               });
+                           try {
+                              while (true) {
+                                watcher.check();
+                                Thread.sleep(interval);
+                              }
+                            } catch (InterruptedException iex) {
+                                dbManager.closeSession();
+                            }
+                       }       
+               };
+               
+               thr.start();
+               
+       }
 
        public void contextDestroyed(ServletContextEvent event){
                HibernateUtil.getSessionFactory().close(); // Free all resources

Added: incubator/wookie/trunk/src/org/apache/wookie/util/WgtWatcher.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/util/WgtWatcher.java?rev=884338&view=auto
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/util/WgtWatcher.java (added)
+++ incubator/wookie/trunk/src/org/apache/wookie/util/WgtWatcher.java Wed Nov 
25 23:31:16 2009
@@ -0,0 +1,247 @@
+/*
+ * 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.wookie.util;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.log4j.Logger;
+
+/**
+ * <p>
+ * The <b>WgtWatcher </b> watches the deployDir for changes made to the
+ * directory (adding new WGT files->deploy) And
+ * notifies a listener of the changes made
+ * </p>
+ * <p>
+ * Based on org.apache.catalina.cluster.deploy.WarWatcher
+ * </p>
+ * @author Scott Wilson
+ * @author Filip Hanik
+ * @author Peter Rossbach
+ * @version 1.1
+ */
+
+public class WgtWatcher {
+
+    /*--Static Variables----------------------------------------*/
+       static Logger log = Logger.getLogger(WgtWatcher.class.getName());       
+
+    /*--Instance Variables--------------------------------------*/
+    /**
+     * Directory to watch for war files
+     */
+    protected File watchDir = null;
+
+    /**
+     * Parent to be notified of changes
+     */
+    protected FileChangeListener listener = null;
+
+    /**
+     * Currently deployed files
+     */
+    protected Map currentStatus = new ConcurrentHashMap();
+
+    /*--Constructor---------------------------------------------*/
+
+    public WgtWatcher() {
+    }
+
+    public WgtWatcher(FileChangeListener listener, File watchDir) {
+        this.listener = listener;
+        this.watchDir = watchDir;
+    }
+
+    /*--Logic---------------------------------------------------*/
+
+    /**
+     * check for modification and send notifcation to listener
+     */
+    public void check() {
+        if (log.isInfoEnabled())
+            log.debug("check for new widgets at " + watchDir);
+        File[] list = watchDir.listFiles(new WgtFilter());
+        if (list == null)
+            list = new File[0];
+        //first make sure all the files are listed in our current status
+        for (int i = 0; i < list.length; i++) {
+            addWarInfo(list[i]);
+        }
+
+        //check all the status codes and update the FarmDeployer
+        for (Iterator i = currentStatus.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry) i.next();
+            WarInfo info = (WarInfo) entry.getValue();
+            int check = info.check();
+            if (check == 1) {
+                listener.fileModified(info.getWar());
+            } else if (check == -1) {
+                listener.fileRemoved(info.getWar());
+                //no need to keep in memory
+                currentStatus.remove(info.getWar().getAbsolutePath());
+            }
+        }
+
+    }
+
+    /**
+     * add cluster war to the watcher state
+     * @param warfile
+     */
+    protected void addWarInfo(File warfile) {
+        WarInfo info = (WarInfo) currentStatus.get(warfile.getAbsolutePath());
+        if (info == null) {
+            info = new WarInfo(warfile);
+            info.setLastState(-1); //assume file is non existent
+            currentStatus.put(warfile.getAbsolutePath(), info);
+        }
+    }
+
+    /**
+     * clear watcher state
+     */
+    public void clear() {
+        currentStatus.clear();
+    }
+
+    /**
+     * @return Returns the watchDir.
+     */
+    public File getWatchDir() {
+        return watchDir;
+    }
+
+    /**
+     * @param watchDir
+     *            The watchDir to set.
+     */
+    public void setWatchDir(File watchDir) {
+        this.watchDir = watchDir;
+    }
+
+    /**
+     * @return Returns the listener.
+     */
+    public FileChangeListener getListener() {
+        return listener;
+    }
+
+    /**
+     * @param listener
+     *            The listener to set.
+     */
+    public void setListener(FileChangeListener listener) {
+        this.listener = listener;
+    }
+
+    /*--Inner classes-------------------------------------------*/
+
+    /**
+     * File name filter for wgt files
+     */
+    protected class WgtFilter implements java.io.FilenameFilter {
+        public boolean accept(File path, String name) {
+            if (name == null)
+                return false;
+            return name.endsWith(".wgt");
+        }
+    }
+
+    /**
+     * File information on existing WAR files
+     */
+    protected class WarInfo {
+        protected File war = null;
+
+        protected long lastChecked = 0;
+
+        protected long lastState = 0;
+
+        public WarInfo(File war) {
+            this.war = war;
+            this.lastChecked = war.lastModified();
+            if (!war.exists())
+                lastState = -1;
+        }
+
+        public boolean modified() {
+            return war.exists() && war.lastModified() > lastChecked;
+        }
+
+        public boolean exists() {
+            return war.exists();
+        }
+
+        /**
+         * Returns 1 if the file has been added/modified, 0 if the file is
+         * unchanged and -1 if the file has been removed
+         * 
+         * @return int 1=file added; 0=unchanged; -1=file removed
+         */
+        public int check() {
+            //file unchanged by default
+            int result = 0;
+
+            if (modified()) {
+                //file has changed - timestamp
+                result = 1;
+                lastState = result;
+            } else if ((!exists()) && (!(lastState == -1))) {
+                //file was removed
+                result = -1;
+                lastState = result;
+            } else if ((lastState == -1) && exists()) {
+                //file was added
+                result = 1;
+                lastState = result;
+            }
+            this.lastChecked = System.currentTimeMillis();
+            return result;
+        }
+
+        public File getWar() {
+            return war;
+        }
+
+        public int hashCode() {
+            return war.getAbsolutePath().hashCode();
+        }
+
+        public boolean equals(Object other) {
+            if (other instanceof WarInfo) {
+                WarInfo wo = (WarInfo) other;
+                return wo.getWar().equals(getWar());
+            } else {
+                return false;
+            }
+        }
+
+        protected void setLastState(int lastState) {
+            this.lastState = lastState;
+        }
+
+    }
+    public interface FileChangeListener {
+        public void fileModified(File f);
+        public void fileRemoved(File f);
+    }
+
+}
\ No newline at end of file

Modified: 
incubator/wookie/trunk/src/org/apache/wookie/util/WidgetPackageUtils.java
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/util/WidgetPackageUtils.java?rev=884338&r1=884337&r2=884338&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/util/WidgetPackageUtils.java 
(original)
+++ incubator/wookie/trunk/src/org/apache/wookie/util/WidgetPackageUtils.java 
Wed Nov 25 23:31:16 2009
@@ -23,12 +23,10 @@
 import java.util.Iterator;
 import java.util.List;
 
-import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 import org.apache.commons.compress.archivers.zip.ZipFile;
-import org.apache.commons.configuration.Configuration;
 import org.apache.commons.fileupload.DiskFileUpload;
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.fileupload.FileUploadBase;
@@ -40,6 +38,8 @@
 import org.apache.wookie.exceptions.InvalidStartFileException;
 import org.apache.wookie.manifestmodel.IManifestModel;
 import org.apache.wookie.manifestmodel.IW3CXMLConfiguration;
+import org.apache.wookie.manifestmodel.impl.ContentEntity;
+import org.apache.wookie.manifestmodel.impl.WidgetManifestModel;
 
 /**
  * Utilities for working with Widget packages, i.e. Zip Files with an XML 
manifest
@@ -78,22 +78,20 @@
                        throw new InvalidStartFileException(); //$NON-NLS-1$
                return startFile;
        }
-
-       public static File createUnpackedWidgetFolder(HttpServletRequest 
request, Configuration properties, String folder) throws IOException{
+       
+       public static File createUnpackedWidgetFolder(String widgetFolder, 
String folder) throws IOException{
                folder = convertIdToFolderName(folder);
-               String uploadPath = 
properties.getString("widget.widgetfolder"); //$NON-NLS-1$
-               ServletContext context = 
request.getSession().getServletContext();
-               String serverPath = context.getRealPath(uploadPath + 
File.separator + folder) ;
+               String serverPath = widgetFolder + File.separator + folder;
                File file = new File(convertPathToPlatform(serverPath));
                return file;
        }
 
-       public static String getURLForWidget(Configuration properties, String 
folder, String file){
+       public static String getURLForWidget(String widgetFolder, String 
folder, String file){
                folder = convertIdToFolderName(folder);
-               String path = convertPathToRelativeUri("/wookie" + 
properties.getString("widget.widgetfolder") + File.separator + folder + 
File.separator + file); //$NON-NLS-1$ //$NON-NLS-2$
+               String path = convertPathToRelativeUri("/wookie" + widgetFolder 
+ File.separator + folder + File.separator + file); //$NON-NLS-1$ //$NON-NLS-2$
                return path;
        }
-
+       
        public static String convertIdToFolderName(String folder){
                if(folder.startsWith("http://";)){ //$NON-NLS-1$
                        folder = folder.substring(7, folder.length());
@@ -101,12 +99,18 @@
                folder.replaceAll(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$
                return folder;
        }
+       
+       public static File dealWithDroppedFile(String uploadPath, File file) 
throws Exception{  
+               String serverPath = convertPathToPlatform(uploadPath);
+               File uFile = new File(serverPath + File.separator + 
file.getName());
+               FileUtils.copyFile(file, uFile);
+               file.delete();
+               return uFile;
+       }
 
-       public static File dealWithUploadFile(HttpServletRequest request, 
Configuration properties) throws Exception {
+       public static File dealWithUploadFile(String uploadPath, 
HttpServletRequest request) throws Exception {
                File uFile = null;
-               String uploadPath = 
properties.getString("widget.useruploadfolder"); //$NON-NLS-1$
-               ServletContext context = 
request.getSession().getServletContext();
-               String serverPath = 
convertPathToPlatform(context.getRealPath(uploadPath));
+               String serverPath = convertPathToPlatform(uploadPath);
                _logger.debug(serverPath);
                String archiveFileName = null;
                if (FileUploadBase.isMultipartContent(request)) {
@@ -152,11 +156,9 @@
                return result;
        }
 
-       public static boolean removeWidgetResources(HttpServletRequest request, 
Configuration properties, String folder){
-               folder = convertIdToFolderName(folder);
-               String uploadPath = 
properties.getString("widget.widgetfolder"); //$NON-NLS-1$
-               ServletContext context = 
request.getSession().getServletContext();
-               String serverPath = context.getRealPath(uploadPath + 
File.separator + folder) ;
+       public static boolean removeWidgetResources(String WIDGETFOLDER, String 
widgetGuid){
+               String folder = convertIdToFolderName(widgetGuid);
+               String serverPath = WIDGETFOLDER + File.separator + folder;
                File pFolder = new File(convertPathToPlatform(serverPath));
                try {
                        _logger.debug("Deleting 
folder:"+pFolder.getCanonicalFile().toString()); //$NON-NLS-1$
@@ -169,6 +171,56 @@
                return true;
        }
        
+       public static IManifestModel processWidgetPackage(File zipFile, String 
localWidgetPath, String WIDGETFOLDER, String UPLOADFOLDER) throws 
BadWidgetZipFileException, BadManifestException{
+               ZipFile zip;
+               try {
+                       zip = new ZipFile(zipFile);
+               } catch (IOException e) {
+                       throw new BadWidgetZipFileException();
+               }
+               if (WidgetPackageUtils.hasManifest(zip)){
+                       try {
+                               // build the model
+                               IManifestModel widgetModel = new 
WidgetManifestModel(WidgetPackageUtils.extractManifest(zip), zip);              
                                                                                
                       
+                               // get the start file; if there is no valid 
start file an exception will be thrown
+                               String src = 
WidgetPackageUtils.locateStartFile(widgetModel, zip);
+                               // get the widget identifier
+                               String manifestIdentifier = 
widgetModel.getIdentifier();                                                
+                               // create the folder structure to unzip the zip 
into
+                               File newWidgetFolder = 
WidgetPackageUtils.createUnpackedWidgetFolder(WIDGETFOLDER, manifestIdentifier);
+                               // now unzip it into that folder
+                               WidgetPackageUtils.unpackZip(zip, 
newWidgetFolder);                                                     
+                               // get the url to the start page
+                               String relativestartUrl = 
(WidgetPackageUtils.getURLForWidget(localWidgetPath, manifestIdentifier, src));
+                               // update the model version of the start page 
(or create one if none exists)
+                               if (widgetModel.getContent() == null) 
widgetModel.setContent(new ContentEntity()); 
+                               
widgetModel.getContent().setSrc(relativestartUrl);
+                               // now update the js links in the start page
+                               File startFile = new 
File(newWidgetFolder.getCanonicalPath() + File.separator + src);                
                                   
+                               if(startFile.exists()){                         
                                
+                                       StartPageJSParser parser = new 
StartPageJSParser(startFile, widgetModel);
+                                       parser.doParse();
+                               }                                               
        
+                               // get the path to the root of the unzipped 
folder
+                               String localPath = 
WidgetPackageUtils.getURLForWidget(localWidgetPath, manifestIdentifier, "");
+                               // now pass this to the model which will 
prepend the path to local resources (not web icons)
+                               widgetModel.updateIconPaths(localPath);         
                                        
+                               // check to see if this widget already exists 
in the DB - using the ID (guid) key from the manifest
+                               return widgetModel;
+                       } catch (InvalidStartFileException e) {
+                               throw e;
+                       } catch (BadManifestException e) {
+                               throw e;
+                       } catch (Exception e){
+                               throw new BadManifestException();
+                       }
+               }
+               else{
+                       // no manifest file found in zip archive
+                       throw new BadWidgetZipFileException(); //$NON-NLS-1$ 
+               }
+       }
+       
        /**
         * Checks for the existence of the Manifest.
         * TODO not sure if this properly handles case-sensitive entries?
@@ -191,7 +243,7 @@
        }
 
        /**
-        * uses apache commons compress to unpack all the zipe entries into a 
target folder
+        * uses apache commons compress to unpack all the zip entries into a 
target folder
         * partly adapted from the examples on the apache commons compress 
site, and an
         * example of generic Zip unpacking. Note this iterates over the 
ZipArchiveEntry enumeration rather
         * than use the more typical ZipInputStream parsing model, as according 
to the doco it will

Modified: incubator/wookie/trunk/src/widgetserver.properties
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/widgetserver.properties?rev=884338&r1=884337&r2=884338&view=diff
==============================================================================
--- incubator/wookie/trunk/src/widgetserver.properties (original)
+++ incubator/wookie/trunk/src/widgetserver.properties Wed Nov 25 23:31:16 2009
@@ -14,6 +14,11 @@
 widget.useruploadfolder=/upload
 widget.widgetfolder=/wservices
 #######################################################################
+# Set hot_deploy to true, and .wgt files dropped into widget.deployfolder
+# will automatically be added to the server
+widget.deployfolder=/deploy
+widget.hot_deploy=false
+#######################################################################
 # Location of Shindig services
 widget.shindig.url=/wookie
 widget.metadata.url=/wookie/gadgets/metadata


Reply via email to