roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject svn commit: r739576 [1/2] - in /roller/branches/roller_mediablogging/apps/weblogger: nbproject/ src/java/META-INF/ src/java/org/apache/roller/weblogger/business/ src/java/org/apache/roller/weblogger/business/jpa/ src/java/org/apache/roller/weblogger/po...
Date Sat, 31 Jan 2009 16:49:52 GMT
Author: snoopdave
Date: Sat Jan 31 16:49:51 2009
New Revision: 739576

URL: http://svn.apache.org/viewvc?rev=739576&view=rev
Log:
(NOTE: this commit is to roller_mediablogging branch)

Commiting Media Blogging patch from Ganesh, corresponding issue is here:
   https://issues.apache.org/roller/browse/ROL-1765

This is ongoing work with lots more to come. The commit contains:
- New database tables and indexes
- New manager interfaces, implementaitons and POJOs
- New Struts actions and JSP pages

I made some small changes:
- Added new tables and indexes from createdb.vm into migration script
- Added menu item for the new Add Media File to Create & Edit menu
  (maybe not the right place for it, but it'll do for now)
- Added link in Add Media File page to the Tabular action

There is some code in one of these test that has references to drive c local
files that should probably be cleaned up.

Added:
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManager.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManagerImpl.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManager.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManagerImpl.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/FileContent.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.orm.xml
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.orm.xml
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/rendering/servlets/MediaResourceServlet.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd-validation.xml
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileBean.java
    roller/branches/roller_mediablogging/apps/weblogger/test/java/org/apache/roller/weblogger/business/FileContentManagerTest.java
    roller/branches/roller_mediablogging/apps/weblogger/test/java/org/apache/roller/weblogger/business/MediaFileTest.java
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/jsps/editor/MediaFileAdd.jsp
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/jsps/editor/MediaFileAddSuccess.jsp
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/jsps/editor/MediaFileSidebar.jsp
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/jsps/editor/TabularView.jsp
Modified:
    roller/branches/roller_mediablogging/apps/weblogger/nbproject/project.xml
    roller/branches/roller_mediablogging/apps/weblogger/src/java/META-INF/persistence.xml
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/Weblogger.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/WebloggerImpl.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerImpl.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java
    roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/editor-menu.xml
    roller/branches/roller_mediablogging/apps/weblogger/src/sql/400-to-410-migration.vm
    roller/branches/roller_mediablogging/apps/weblogger/src/sql/createdb.vm
    roller/branches/roller_mediablogging/apps/weblogger/src/sql/droptables.sql
    roller/branches/roller_mediablogging/apps/weblogger/test/java/org/apache/roller/weblogger/ant/StartDerbyTask.java
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/classes/ApplicationResources.properties
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/classes/struts.xml
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/tiles.xml
    roller/branches/roller_mediablogging/apps/weblogger/web/WEB-INF/web.xml

Modified: roller/branches/roller_mediablogging/apps/weblogger/nbproject/project.xml
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/nbproject/project.xml?rev=739576&r1=739575&r2=739576&view=diff
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/nbproject/project.xml (original)
+++ roller/branches/roller_mediablogging/apps/weblogger/nbproject/project.xml Sat Jan 31 16:49:51 2009
@@ -4,7 +4,7 @@
     <configuration>
         <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
             <!-- Do not use Project Properties customizer when editing this file manually. -->
-            <name>roller_weblogger_trunk</name>
+            <name>roller_weblogger_mediablogging</name>
             <properties>
                 <property name="ant.script">build.xml</property>
             </properties>

Modified: roller/branches/roller_mediablogging/apps/weblogger/src/java/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/META-INF/persistence.xml?rev=739576&r1=739575&r2=739576&view=diff
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/META-INF/persistence.xml (original)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/META-INF/persistence.xml Sat Jan 31 16:49:51 2009
@@ -28,6 +28,9 @@
         <mapping-file>org/apache/roller/weblogger/pojos/WeblogPermission.orm.xml               </mapping-file>
         <mapping-file>org/apache/roller/weblogger/pojos/Weblog.orm.xml                         </mapping-file>
         <mapping-file>org/apache/roller/weblogger/pojos/UserAttribute.orm.xml                  </mapping-file>	
+        <mapping-file>org/apache/roller/weblogger/pojos/MediaFile.orm.xml                      </mapping-file>	
+        <mapping-file>org/apache/roller/weblogger/pojos/MediaFileTag.orm.xml                   </mapping-file>	
+        <mapping-file>org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml             </mapping-file>	
     </persistence-unit> 
     
 </persistence>

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManager.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManager.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManager.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManager.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.business;
+
+import java.io.InputStream;
+
+import org.apache.roller.weblogger.pojos.FileContent;
+import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.util.RollerMessages;
+
+
+/**
+ * Interface for managing contents of the files uploaded to Roller.
+ */
+public interface FileContentManager {
+    
+    /**
+     * Get a reference to the content of a specific file in a weblog's uploads area.
+     * 
+     * This method always returns a valid file content object or will throw an exception
+     * if the specificed path doesn't exist, or can't be read.
+     * 
+     * @param weblog The weblog we are working on.
+     * @param path The relative path to the desired resource within 
+     * the weblog's uploads area.
+     *
+     * @throws FileNotFoundException If path does not exist.
+     * @throws FilePathException If path is invalid, or can't be read.
+     */
+    public FileContent getFileContent(Weblog weblog, String fileId) 
+    throws FileNotFoundException, FilePathException;
+    
+    
+    /**
+     * Save a file's content to weblog's uploads area.
+     * 
+     * @param weblog The weblog we are working on.
+     * @param fileId file identifier from database.
+     * @param is InputStream to read the file from.
+     *
+     * @throws FileNotFoundException If path to save location does not exist.
+     * @throws FilePathException If path is invalid, is not a directory, or can't be read.
+     * @throws FileIOException If there is an unexpected error during the save.
+     */
+    public void saveFileContent(Weblog weblog, 
+            String fileId,
+            InputStream is) 
+    throws FileNotFoundException, FilePathException, FileIOException;
+    
+    
+    /**
+     * Delete file content from weblog's uploads area.
+     * 
+     * @param weblog The weblog we are working on.
+     * @param fileId file identifier from database.
+     *
+     * @throws FileNotFoundException If path does not exist.
+     * @throws FilePathException If path is invalid, or can't be read.
+     * @throws FileIOException If there is an unexpected error during the delete.
+     */
+    public void deleteFile(Weblog weblog, String fileId) 
+        throws FileNotFoundException, FilePathException, FileIOException;
+    
+    
+    /**
+     * Delete all files associated with a given weblog.
+     *
+     * The only real use of this method is for when a weblog is being deleted.
+     *
+     * @param weblog The weblog to delete all files from.
+     * @throws FileIOException If there is an unexpected error during the delete.
+     */
+    public void deleteAllFiles(Weblog weblog)
+        throws FileIOException;
+    
+    
+    /** 
+     * Is the given weblog over the file-upload quota limit?
+     *
+     * @param weblog The weblog we are working on.
+     * @return True if weblog is over set quota, False otherwise.
+     */
+    public boolean overQuota(Weblog weblog);
+    
+    /**
+     * Determine if file can be saved given current WebloggerConfig settings.
+     */
+    public boolean canSave(Weblog weblog,
+    		               String fileName,
+                           String contentType,
+                           long size, 
+                           RollerMessages messages);
+    
+    /**
+     * Release all resources associated with Roller session.
+     */
+    public void release();
+    
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManagerImpl.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManagerImpl.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManagerImpl.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/FileContentManagerImpl.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,403 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.business;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.weblogger.config.WebloggerConfig;
+import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
+import org.apache.roller.weblogger.pojos.FileContent;
+import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.util.RollerMessages;
+
+
+/**
+ * Manages contents of the file uploaded to Roller weblogs.  
+ * 
+ * This base implementation writes file content to a file system.
+ */
+public class FileContentManagerImpl implements FileContentManager {
+	
+    private static Log log = LogFactory.getLog(FileContentManagerImpl.class);
+    
+    private String upload_dir = null;
+    
+    
+    /**
+     * Create file content manager.
+     */
+    public FileContentManagerImpl() {
+        String uploaddir = WebloggerConfig.getProperty("uploads.dir");
+        
+        // Note: System property expansion is now handled by WebloggerConfig.
+        
+        if(uploaddir == null || uploaddir.trim().length() < 1)
+            uploaddir = System.getProperty("user.home") + File.separator+"roller_data"+File.separator+"uploads";
+        
+        if( ! uploaddir.endsWith(File.separator))
+            uploaddir += File.separator;
+        
+        this.upload_dir = uploaddir.replace('/',File.separatorChar);
+    }
+    
+    
+    /**
+     * @see org.apache.roller.weblogger.model.FileContentManager#getFileContent(weblog, java.lang.String)
+     */
+    public FileContent getFileContent(Weblog weblog, String fileId) 
+            throws FileNotFoundException, FilePathException {
+        
+        // get a reference to the file, checks that file exists & is readable
+        File resourceFile = this.getRealFile(weblog, fileId);
+        
+        // make sure file is not a directory
+        if(resourceFile.isDirectory()) {
+            throw new FilePathException("Invalid file id ["+fileId+"], "+
+                    "path is a directory.");
+        }
+        
+        // everything looks good, return resource
+        return new FileContent(weblog, fileId, resourceFile);
+    }
+    
+    /**
+     * @see org.apache.roller.weblogger.model.FileContentManager#saveFileContent(weblog, java.lang.String, 
+     * java.lang.String, java.io.InputStream, boolean)
+     */
+    public void saveFileContent(Weblog weblog, 
+                         String fileId, 
+                         InputStream is)
+            throws FileNotFoundException, FilePathException, FileIOException {
+        
+        // make sure uploads area exists for this weblog
+        File dirPath = this.getRealFile(weblog, null);
+        
+        // create File that we are about to save
+        File saveFile = new File(dirPath.getAbsolutePath() + File.separator + fileId);
+        
+        byte[] buffer = new byte[8192];
+        int bytesRead = 0;
+        OutputStream bos = null;
+        try {
+            bos = new FileOutputStream(saveFile);
+            while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
+                bos.write(buffer, 0, bytesRead);
+            }
+            
+            log.debug("The file has been written to ["+saveFile.getAbsolutePath()+"]");
+        } catch (Exception e) {
+            throw new FileIOException("ERROR uploading file", e);
+        } finally {
+            try {
+                bos.flush();
+                bos.close();
+            } catch (Exception ignored) {}
+        }
+        
+        
+    }
+    
+    
+    /**
+     * @see org.apache.roller.weblogger.model.FileContentManager#deleteFile(weblog, java.lang.String)
+     */
+    public void deleteFile(Weblog weblog, String fileId) 
+            throws FileNotFoundException, FilePathException, FileIOException {
+        
+        // get path to delete file, checks that path exists and is readable
+        File delFile = this.getRealFile(weblog, fileId);
+        
+        if(!delFile.delete()) {
+            throw new FileIOException("Delete failed for ["+fileId+"], "+
+                    "possibly a non-empty directory?");
+        }
+    }
+    
+    /**
+     * @inheritDoc
+     */
+    public void deleteAllFiles(Weblog weblog) throws FileIOException {
+        // TODO: Implement
+    }
+    
+    /**
+     * @see org.apache.roller.weblogger.model.FileContentManager#overQuota(weblog)
+     */
+    public boolean overQuota(Weblog weblog) {
+        
+        String maxDir = WebloggerRuntimeConfig.getProperty("uploads.dir.maxsize");
+        String maxFile = WebloggerRuntimeConfig.getProperty("uploads.file.maxsize");
+        BigDecimal maxDirSize = new BigDecimal(maxDir); // in megabytes
+        BigDecimal maxFileSize = new BigDecimal(maxFile); // in megabytes
+        
+        long maxDirBytes = (long)(1024000 * maxDirSize.doubleValue());
+        
+        try {
+            File uploadsDir = this.getRealFile(weblog, null);
+            long weblogDirSize = this.getDirSize(uploadsDir, true);
+            
+            return weblogDirSize > maxDirBytes;
+        } catch (Exception ex) {
+            // shouldn't ever happen, this means user's uploads dir is bad
+            // rethrow as a runtime exception
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    
+    public void release() {
+    }
+    
+    
+    /**
+     * Determine if file can be saved given current WebloggerConfig settings.
+     */
+    public boolean canSave(Weblog weblog,
+    		               String fileName,
+                           String contentType,
+                           long size, 
+                           RollerMessages messages) {
+        
+        // first check, is uploading enabled?
+        if(!WebloggerRuntimeConfig.getBooleanProperty("uploads.enabled")) {
+            messages.addError("error.upload.disabled");
+            return false;
+        }
+        
+        // second check, does upload exceed max size for file?
+        BigDecimal maxFileMB = new BigDecimal(
+                WebloggerRuntimeConfig.getProperty("uploads.file.maxsize"));
+        int maxFileBytes = (int)(1024000 * maxFileMB.doubleValue());
+        log.debug("max allowed file size = "+maxFileBytes);
+        log.debug("attempted save file size = "+size);
+        if (size > maxFileBytes) {
+            messages.addError("error.upload.filemax", maxFileMB.toString());
+            return false;
+        }
+        
+        // third check, does file cause weblog to exceed quota?
+        BigDecimal maxDirMB = new BigDecimal(
+                WebloggerRuntimeConfig.getProperty("uploads.dir.maxsize"));
+        long maxDirBytes = (long)(1024000 * maxDirMB.doubleValue());
+        try {
+            File uploadsDir = this.getRealFile(weblog, null);
+            long userDirSize = getDirSize(uploadsDir, true);
+            if (userDirSize + size > maxDirBytes) {
+                messages.addError("error.upload.dirmax", maxDirMB.toString());
+                return false;
+            }
+        } catch (Exception ex) {
+            // shouldn't ever happen, means the weblogs uploads dir is bad somehow
+            // rethrow as a runtime exception
+            throw new RuntimeException(ex);
+        }
+        
+        // fourth check, is upload type allowed?
+        String allows = WebloggerRuntimeConfig.getProperty("uploads.types.allowed");
+        String forbids = WebloggerRuntimeConfig.getProperty("uploads.types.forbid");
+        String[] allowFiles = StringUtils.split(StringUtils.deleteWhitespace(allows), ",");
+        String[] forbidFiles = StringUtils.split(StringUtils.deleteWhitespace(forbids), ",");
+        if (!checkFileType(allowFiles, forbidFiles, fileName, contentType)) {
+            messages.addError("error.upload.forbiddenFile", allows);
+            return false;
+        }
+        
+        return true;
+    }
+    
+    
+    /**
+     * Get the size in bytes of given directory.
+     *
+     * Optionally works recursively counting subdirectories if they exist.
+     */
+    private long getDirSize(File dir, boolean recurse) {
+        
+        long size = 0;
+        if(dir.exists() && dir.isDirectory() && dir.canRead()) {
+            File[] files = dir.listFiles();
+            long dirSize = 0l;
+            for (int i=0; i < files.length; i++) {
+                if (!files[i].isDirectory()) {
+                    dirSize += files[i].length();
+                } else if(recurse) {
+                    // count a subdirectory
+                    dirSize += getDirSize(files[i], recurse);
+                }
+            }
+            size += dirSize;
+        }
+        
+        return size;
+    }
+    
+    
+    /**
+     * Return true if file is allowed to be uplaoded given specified allowed and
+     * forbidden file types.
+     */
+    private boolean checkFileType(String[] allowFiles, String[] forbidFiles,
+                                  String fileName, String contentType) {
+        
+        // TODO: Atom Publushing Protocol figure out how to handle file
+        // allow/forbid using contentType.
+        // TEMPORARY SOLUTION: In the allow/forbid lists we will continue to
+        // allow user to specify file extensions (e.g. gif, png, jpeg) but will
+        // now also allow them to specify content-type rules (e.g. */*, image/*,
+        // text/xml, etc.).
+        
+        // if content type is invalid, reject file
+        if (contentType == null || contentType.indexOf("/") == -1)  {
+            return false;
+        }
+        
+        // default to false
+        boolean allowFile = false;
+        
+        // if this person hasn't listed any allows, then assume they want
+        // to allow *all* filetypes, except those listed under forbid
+        if(allowFiles == null || allowFiles.length < 1) {
+            allowFile = true;
+        }
+        
+        // First check against what is ALLOWED
+        
+        // check file against allowed file extensions
+        if (allowFiles != null && allowFiles.length > 0) {
+            for (int y=0; y<allowFiles.length; y++) {
+                // oops, this allowed rule is a content-type, skip it
+                if (allowFiles[y].indexOf("/") != -1) continue;
+                if (fileName.toLowerCase().endsWith(
+                        allowFiles[y].toLowerCase())) {
+                    allowFile = true;
+                    break;
+                }
+            }
+        }
+        
+        // check file against allowed contentTypes
+        if (allowFiles != null && allowFiles.length > 0) {
+            for (int y=0; y<allowFiles.length; y++) {
+                // oops, this allowed rule is NOT a content-type, skip it
+                if (allowFiles[y].indexOf("/") == -1) continue;
+                if (matchContentType(allowFiles[y], contentType)) {
+                    allowFile = true;
+                    break;
+                }
+            }
+        }
+        
+        // First check against what is FORBIDDEN
+        
+        // check file against forbidden file extensions, overrides any allows
+        if (forbidFiles != null && forbidFiles.length > 0) {
+            for (int x=0; x<forbidFiles.length; x++) {
+                // oops, this forbid rule is a content-type, skip it
+                if (forbidFiles[x].indexOf("/") != -1) continue;
+                if (fileName.toLowerCase().endsWith(
+                        forbidFiles[x].toLowerCase())) {
+                    allowFile = false;
+                    break;
+                }
+            }
+        }
+        
+        
+        // check file against forbidden contentTypes, overrides any allows
+        if (forbidFiles != null && forbidFiles.length > 0) {
+            for (int x=0; x<forbidFiles.length; x++) {
+                // oops, this forbid rule is NOT a content-type, skip it
+                if (forbidFiles[x].indexOf("/") == -1) continue;
+                if (matchContentType(forbidFiles[x], contentType)) {
+                    allowFile = false;
+                    break;
+                }
+            }
+        }
+        
+        return allowFile;
+    }
+    
+    
+    /**
+     * Super simple contentType range rule matching
+     */
+    private boolean matchContentType(String rangeRule, String contentType) {
+        if (rangeRule.equals("*/*")) return true;
+        if (rangeRule.equals(contentType)) return true;
+        String ruleParts[] = rangeRule.split("/");
+        String typeParts[] = contentType.split("/");
+        if (ruleParts[0].equals(typeParts[0]) && ruleParts[1].equals("*")) 
+            return true;
+        
+        return false;
+    }
+    
+    
+    /**
+     * Construct the full real path to a resource in a weblog's uploads area.
+     */
+    private File getRealFile(Weblog weblog, String fileId) 
+            throws FileNotFoundException, FilePathException {
+        
+        // make sure uploads area exists for this weblog
+        File weblogDir = new File(this.upload_dir + weblog.getHandle());
+        if(!weblogDir.exists()) {
+            weblogDir.mkdirs();
+        }
+        
+        // now form the absolute path
+        String filePath = weblogDir.getAbsolutePath();
+        if (fileId != null) {
+            filePath += File.separator + fileId;
+        }
+        
+        // make sure path exists and is readable
+        File file = new File(filePath);
+        if(!file.exists()) {
+            throw new FileNotFoundException("Invalid path ["+filePath+"], "+
+                    "directory doesn't exist.");
+        } else if(!file.canRead()) {
+            throw new FilePathException("Invalid path ["+filePath+"], "+
+                    "cannot read from path.");
+        }
+        
+        try {
+            // make sure someone isn't trying to sneek outside the uploads dir
+            if(!file.getCanonicalPath().startsWith(weblogDir.getCanonicalPath())) {
+                throw new FilePathException("Invalid path "+filePath+"], "+
+                        "trying to get outside uploads dir.");
+            }
+        } catch (IOException ex) {
+            // rethrow as FilePathException
+            throw new FilePathException(ex);
+        }
+        
+        return file;
+    }
+    
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManager.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManager.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManager.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManager.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.business;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.roller.weblogger.WebloggerException;
+import org.apache.roller.weblogger.pojos.MediaFile;
+import org.apache.roller.weblogger.pojos.MediaFileDirectory;
+import org.apache.roller.weblogger.pojos.Weblog;
+
+public interface MediaFileManager {
+
+	// TODO: Ganesh - Remove old FileManager implementation
+	public void createMediaFile(Weblog weblog, MediaFile mediaFile) throws WebloggerException ;
+	public void updateMediaFile(Weblog weblog, MediaFile mediaFile) throws WebloggerException ;
+	public MediaFile getMediaFile(String id) throws WebloggerException;
+	public MediaFile getMediaFile(String id, boolean includeContent) throws WebloggerException;
+	public void removeMediaFile(MediaFile mediaFile) throws WebloggerException;
+	
+	public MediaFileDirectory createRootMediaFileDirectory(Weblog weblog) throws WebloggerException;
+	public void createMediaFileDirectory(MediaFileDirectory directory) throws WebloggerException;
+
+	public MediaFileDirectory getMediaFileDirectory(String id) throws WebloggerException;
+	public List<MediaFileDirectory> getMediaFileDirectories(Weblog weblog) throws WebloggerException;
+    public MediaFileDirectory getMediaFileRootDirectory(Weblog weblog) throws WebloggerException;
+    
+    public void moveMediaFiles(Collection<MediaFile> mediaFiles, MediaFileDirectory directory) throws WebloggerException;
+
+	public void release();
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManagerImpl.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManagerImpl.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManagerImpl.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/MediaFileManagerImpl.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.business;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.NoResultException;
+import javax.persistence.OneToMany;
+import javax.persistence.Query;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.weblogger.WebloggerException;
+import org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy;
+import org.apache.roller.weblogger.pojos.FileContent;
+import org.apache.roller.weblogger.pojos.MediaFile;
+import org.apache.roller.weblogger.pojos.MediaFileDirectory;
+import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.pojos.WeblogBookmarkFolder;
+import org.apache.roller.weblogger.util.RollerMessages;
+
+@com.google.inject.Singleton
+public class MediaFileManagerImpl implements MediaFileManager {
+	
+    private final Weblogger roller;
+    private final JPAPersistenceStrategy persistenceStrategy;
+    
+    /**
+     * Creates a new instance of MediaFileManagerImpl
+     */
+   @com.google.inject.Inject
+	protected MediaFileManagerImpl(Weblogger roller, JPAPersistenceStrategy persistenceStrategy) {
+	   this.roller = roller;
+	   this.persistenceStrategy = persistenceStrategy;
+    }
+	
+	/**
+     * The logger instance for this class.
+     */
+    private static Log log = LogFactory
+            .getFactory().getInstance(MediaFileManagerImpl.class);
+
+	public void release() {
+		
+	}
+	
+    @OneToMany
+	public void moveMediaFiles(Collection<MediaFile> mediaFiles, MediaFileDirectory targetDirectory) 
+        throws WebloggerException {
+    	for (MediaFile mediaFile: mediaFiles) {
+    		mediaFile.setDirectory(targetDirectory);
+    		this.persistenceStrategy.store(mediaFile);
+    	}
+        // update weblog last modified date.  date updated by saveWebsite()
+        roller.getWeblogManager().saveWeblog(targetDirectory.getWeblog());
+    }
+
+	
+	public void createMediaFileDirectory(MediaFileDirectory directory) 
+	  throws WebloggerException {
+		this.persistenceStrategy.store(directory);
+        
+        // update weblog last modified date.  date updated by saveWebsite()
+        roller.getWeblogManager().saveWeblog(directory.getWeblog());
+	}
+	
+	public MediaFileDirectory createRootMediaFileDirectory(Weblog weblog) 
+	    throws WebloggerException {
+        MediaFileDirectory rootDirectory = new MediaFileDirectory(null, "root", "root directory", weblog);
+		createMediaFileDirectory(rootDirectory);
+		return rootDirectory;
+	}
+
+	
+
+	public void createMediaFile(Weblog weblog, MediaFile mediaFile) throws WebloggerException {
+		
+        FileContentManager cmgr = WebloggerFactory.getWeblogger().getFileContentManager();
+        RollerMessages msgs = new RollerMessages();
+        if (!cmgr.canSave(weblog, mediaFile.getName(), mediaFile.getContentType(), mediaFile.getLength(), msgs)) {
+            throw new FileIOException(msgs.toString());
+        }
+
+        mediaFile.setDateUploaded(new Timestamp(System.currentTimeMillis()));
+        mediaFile.setLastUpdated(mediaFile.getDateUploaded());
+		persistenceStrategy.store(mediaFile);
+        // update weblog last modified date.  date updated by saveWeblog()
+        roller.getWeblogManager().saveWeblog(weblog);
+        
+        cmgr.saveFileContent(weblog, mediaFile.getId(), mediaFile.getInputStream());
+	}
+	
+	public void updateMediaFile(Weblog weblog, MediaFile mediaFile) throws WebloggerException {
+		mediaFile.setLastUpdated(new Timestamp(System.currentTimeMillis()));
+		persistenceStrategy.store(mediaFile);
+        // update weblog last modified date.  date updated by saveWeblog()
+        roller.getWeblogManager().saveWeblog(weblog);
+	}
+
+	public MediaFile getMediaFile(String id) throws WebloggerException {
+        return getMediaFile(id, false);
+	}
+
+	public MediaFile getMediaFile(String id, boolean includeContent) throws WebloggerException {
+		MediaFile mediaFile = (MediaFile) this.persistenceStrategy.load(MediaFile.class, id);
+		if (includeContent) {
+	        FileContentManager cmgr = WebloggerFactory.getWeblogger().getFileContentManager();
+	        FileContent content = cmgr.getFileContent(mediaFile.getDirectory().getWeblog(), id);
+	        mediaFile.setContent(content);
+		}
+        return mediaFile;
+	}
+
+	public MediaFileDirectory getMediaFileDirectory(String id) 
+	    throws WebloggerException {
+		return (MediaFileDirectory) this.persistenceStrategy.load(MediaFileDirectory.class, id);
+	}
+
+	public MediaFileDirectory getMediaFileRootDirectory(Weblog weblog) 
+    throws WebloggerException {
+        Query q = this.persistenceStrategy.getNamedQuery("MediaFileDirectory.getByWeblogAndNoParent");
+        q.setParameter(1, weblog);
+        try {
+            return (MediaFileDirectory)q.getSingleResult();
+        } catch (NoResultException e) {
+            return null;
+        }
+	}
+
+	public List<MediaFileDirectory> getMediaFileDirectories(Weblog weblog) 
+	    throws WebloggerException {
+        
+        Query q = this.persistenceStrategy.getNamedQuery("MediaFileDirectory.getByWeblog");
+        q.setParameter(1, weblog);
+        return q.getResultList();
+	}
+	
+	public void removeMediaFile(MediaFile mediaFile) 
+	    throws WebloggerException {
+		this.persistenceStrategy.remove(mediaFile);
+	}
+	
+	/*
+	public void searchMediaFiles(MediaFileSearchCriteria searchCriteria) {
+		
+	}
+	*/
+
+}

Modified: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/Weblogger.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/Weblogger.java?rev=739576&r1=739575&r2=739576&view=diff
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/Weblogger.java (original)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/Weblogger.java Sat Jan 31 16:49:51 2009
@@ -132,13 +132,21 @@
      */
     public PluginManager getPluginManager();
     
+    /**
+     * Get MediaFileManager associated with this Weblogger instance.
+     */
+    public MediaFileManager getMediaFileManager();
     
     /**
+     * Get FileContentManager associated with this Weblogger instance.
+     */
+    public FileContentManager getFileContentManager();
+
+    /**
      * Get the URLStrategy used to build all urls in the system.
      */
     public URLStrategy getUrlStrategy();
     
-    
     /**
      * Flush object states.
      */

Modified: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/WebloggerImpl.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/WebloggerImpl.java?rev=739576&r1=739575&r2=739576&view=diff
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/WebloggerImpl.java (original)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/WebloggerImpl.java Sat Jan 31 16:49:51 2009
@@ -53,6 +53,8 @@
     private final BookmarkManager      bookmarkManager;
     private final FileManager          fileManager;
     private final IndexManager         indexManager;
+    private final MediaFileManager     mediaFileManager;
+    private final FileContentManager   fileContentManager;
     private final PingQueueManager     pingQueueManager;
     private final PingTargetManager    pingTargetManager;
     private final PluginManager        pluginManager;
@@ -80,6 +82,8 @@
         BookmarkManager      bookmarkManager,
         FileManager          fileManager,
         IndexManager         indexManager,
+        MediaFileManager     mediaFileManager,
+        FileContentManager   fileContentManager,
         PingQueueManager     pingQueueManager,
         PingTargetManager    pingTargetManager,
         PluginManager        pluginManager,
@@ -97,6 +101,8 @@
         this.bookmarkManager     = bookmarkManager;
         this.fileManager         = fileManager;
         this.indexManager        = indexManager;
+        this.mediaFileManager    = mediaFileManager;
+        this.fileContentManager  = fileContentManager;
         this.pingQueueManager    = pingQueueManager;
         this.pingTargetManager   = pingTargetManager;
         this.pluginManager       = pluginManager;
@@ -196,6 +202,25 @@
     /**
      * 
      * 
+     * @see org.apache.roller.weblogger.modelWebloggerr#getMediaFileManager()
+     */
+    public MediaFileManager getMediaFileManager() {
+        return mediaFileManager;
+    }
+    
+    /**
+     * 
+     * 
+     * @see org.apache.roller.weblogger.modelWebloggerr#getFileContentManager()
+     */
+    public FileContentManager getFileContentManager() {
+        return fileContentManager;
+    }
+    
+    
+    /**
+     * 
+     * 
      * @see org.apache.roller.weblogger.modelWebloggerr#getWeblogEntryManager()
      */
     public WeblogEntryManager getWeblogEntryManager() {
@@ -289,6 +314,8 @@
             autoPingManager.release();
             bookmarkManager.release();
             fileManager.release();
+            mediaFileManager.release();
+            fileContentManager.release();
             pingTargetManager.release();
             pingQueueManager.release();
             pluginManager.release();

Modified: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerImpl.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerImpl.java?rev=739576&r1=739575&r2=739576&view=diff
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerImpl.java (original)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerImpl.java Sat Jan 31 16:49:51 2009
@@ -21,7 +21,9 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.roller.weblogger.WebloggerException;
 import org.apache.roller.weblogger.business.BookmarkManager;
+import org.apache.roller.weblogger.business.FileContentManager;
 import org.apache.roller.weblogger.business.FileManager;
+import org.apache.roller.weblogger.business.MediaFileManager;
 import org.apache.roller.weblogger.business.PropertiesManager;
 import org.apache.roller.weblogger.business.URLStrategy;
 import org.apache.roller.weblogger.business.WebloggerImpl;
@@ -63,6 +65,8 @@
         BookmarkManager      bookmarkManager,
         FileManager          fileManager,
         IndexManager         indexManager,
+        MediaFileManager     mediaFileManager,
+        FileContentManager   fileContentManager,
         PingQueueManager     pingQueueManager,
         PingTargetManager    pingTargetManager,
         PluginManager        pluginManager,
@@ -81,6 +85,8 @@
             bookmarkManager,
             fileManager,
             indexManager,
+            mediaFileManager,
+            fileContentManager,
             pingQueueManager,
             pingTargetManager,
             pluginManager,

Modified: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java?rev=739576&r1=739575&r2=739576&view=diff
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java (original)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAWebloggerModule.java Sat Jan 31 16:49:51 2009
@@ -21,8 +21,12 @@
 import com.google.inject.Binder;
 import com.google.inject.Module;
 import org.apache.roller.weblogger.business.BookmarkManager;
+import org.apache.roller.weblogger.business.FileContentManager;
+import org.apache.roller.weblogger.business.FileContentManagerImpl;
 import org.apache.roller.weblogger.business.FileManager;
 import org.apache.roller.weblogger.business.FileManagerImpl;
+import org.apache.roller.weblogger.business.MediaFileManager;
+import org.apache.roller.weblogger.business.MediaFileManagerImpl;
 import org.apache.roller.weblogger.business.MultiWeblogURLStrategy;
 import org.apache.roller.weblogger.business.PropertiesManager;
 import org.apache.roller.weblogger.business.URLStrategy;
@@ -70,6 +74,8 @@
                 
         binder.bind(ReferrerQueueManager.class).to(ReferrerQueueManagerImpl.class); 
         binder.bind(FileManager.class).to(         FileManagerImpl.class);   
+        binder.bind(MediaFileManager.class).to(    MediaFileManagerImpl.class);
+        binder.bind(FileContentManager.class).to(  FileContentManagerImpl.class);
         binder.bind(IndexManager.class).to(        IndexManagerImpl.class);
         binder.bind(PluginManager.class).to(       PluginManagerImpl.class);    
         binder.bind(ThemeManager.class).to(        ThemeManagerImpl.class);

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/FileContent.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/FileContent.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/FileContent.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/FileContent.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.pojos;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+
+/**
+ * A FileContentManagerImpl specific implementation that represents the content
+ * of a file from file system.
+ *
+ */
+public class FileContent {
+    
+    // the physical java.io.File backing this resource
+    private File resourceFile = null;
+    
+    // the file Id of the resource
+    private String fileId = null;
+    
+    // the weblog the resource is attached to
+    private Weblog weblog = null;
+    
+    
+    public FileContent(Weblog weblog, String fileId, File file) {
+        this.weblog = weblog;
+        this.fileId = fileId;
+        resourceFile = file;
+    }
+    
+    public Weblog getWeblog() {
+        return weblog;
+    }
+    
+    public String getName() {
+        return resourceFile.getName();
+    }
+    
+    public String getFileId() {
+        return fileId;
+    }
+    
+    public long getLastModified() {
+        return resourceFile.lastModified();
+    }
+    
+    public long getLength() {
+        return resourceFile.length();
+    }
+    
+    public InputStream getInputStream() {
+        try {
+            return new FileInputStream(resourceFile);
+        } catch (java.io.FileNotFoundException ex) {
+            // should never happen, rethrow as runtime exception
+            throw new RuntimeException("Error constructing input stream", ex);
+        }
+    }
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.pojos;
+
+import java.io.InputStream;
+import java.sql.Timestamp;
+import java.util.Set;
+
+import org.apache.roller.util.UUIDGenerator;
+
+/**
+ * Media file
+ *
+ * @hibernate.cache usage="read-write"
+ * @hibernate.class lazy="true" table="media_file"
+ */
+public class MediaFile implements ThemeResource {
+
+    // TODO: Ganesh - change class name to WeblogMediaFile?
+    // TODO Ganesh - review all class attributes
+    // TODO Ganesh - database constraints (not null etc) - revisit.
+	
+	final String id;
+    String name;
+    String description;
+    String copyrightText;
+    Boolean isSharedForGallery;
+    long length;
+    Timestamp dateUploaded;
+    Timestamp lastUpdated;
+    MediaFileDirectory directory;
+    Set<MediaFileTag> tags;
+    String contentType;
+    InputStream is;
+    FileContent content;
+    
+    public MediaFile() {
+    	this.id = UUIDGenerator.generateUUID();
+    }
+    
+	/**
+	 * Name for the media file
+	 * 
+     * @ejb:persistent-field
+     * @hibernate.property column="name" non-null="true" unique="false"
+	 */
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * Description for media file
+	 * 
+     * @ejb:persistent-field
+     * @hibernate.property column="description" unique="false"
+	 */
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	/**
+	 * Copyright text for media file
+	 * 
+     * @ejb:persistent-field
+     * @hibernate.property column="copyright_text" unique="false"
+	 */
+	public String getCopyrightText() {
+		return copyrightText;
+	}
+
+	public void setCopyrightText(String copyrightText) {
+		this.copyrightText = copyrightText;
+	}
+
+	/**
+	 * Is media file shared for gallery
+	 * 
+     * @hibernate.property column="is_public" non-null="true" unique="false"
+	 */
+	public Boolean isSharedForGallery() {
+		return isSharedForGallery;
+	}
+
+	public void setSharedForGallery(Boolean isSharedForGallery) {
+		this.isSharedForGallery = isSharedForGallery;
+	}
+
+	/**
+	 * Size of the media file
+	 * 
+     * @ejb:persistent-field
+     * @hibernate.property column="size_in_bytes" non-null="true" unique="false"
+	 */
+	public long getLength() {
+		return length;
+	}
+
+	public void setLength(long length) {
+		this.length = length;
+	}
+
+    /**
+     * @ejb:persistent-field
+     * @hibernate.property column="date_uploaded" non-null="true" unique="false"
+     * @roller.wrapPojoMethod type="simple"
+     */
+	public Timestamp getDateUploaded() {
+		return dateUploaded;
+	}
+
+	public void setDateUploaded(Timestamp dateUploaded) {
+		this.dateUploaded = dateUploaded;
+	}
+
+	public long getLastModified() {
+		return lastUpdated.getTime();
+	}
+
+	/**
+     * @ejb:persistent-field
+     * @hibernate.property column="last_updated" unique="false"
+     * @roller.wrapPojoMethod type="simple"
+     */
+	public Timestamp getLastUpdated() {
+		return lastUpdated;
+	}
+
+	public void setLastUpdated(Timestamp time) {
+		this.lastUpdated = time;
+	}
+
+	public MediaFileDirectory getDirectory() {
+		return directory;
+	}
+
+	public void setDirectory(MediaFileDirectory dir) {
+		this.directory = dir;
+	}
+
+	/*
+	 * Set of tags for this media file
+	 * 
+     * @hibernate.collection-key column="media_file_id"
+     * @hibernate.collection-one-to-many class="org.apache.roller.weblogger.pojos.MediaFileTag"
+     * @hibernate.set lazy="true" inverse="true" cascade="delete" 
+	 */
+	public Set<MediaFileTag> getTags() {
+		return tags;
+	}
+
+	public void setTags(Set<MediaFileTag> tags) {
+		this.tags = tags;
+	}
+
+	/**
+	 * Content type of the media file
+	 * 
+     * @ejb:persistent-field
+     * @hibernate.property column="content_type" non-null="true" unique="false"
+	 */
+	public String getContentType() {
+		return contentType;
+	}
+
+	public void setContentType(String contentType) {
+		this.contentType = contentType;
+	}
+
+    /**
+     * Database surrogate key.
+     *
+     * @roller.wrapPojoMethod type="simple"
+     *
+     * @ejb:persistent-field
+     * @hibernate.id column="id"
+     *  generator-class="assigned"  
+     */
+	public String getId() {
+		return id;
+	}
+
+	public String getPath() {
+		return directory.getPath();
+	}
+
+	public ThemeResource[] getChildren() {
+		// TODO - Ganesh - To be implemented
+		return null;
+	}
+
+	public boolean isDirectory() {
+		return false;
+	}
+
+	public boolean isFile() {
+		return true;
+	}
+
+	public InputStream getInputStream() {
+		if (is != null) {
+			return is;
+		}
+		else if (content != null ){
+			return content.getInputStream();
+		}
+		return null;
+	}
+
+	public void setInputStream(InputStream is) {
+		this.is = is;
+	}
+
+	public void setContent(FileContent content) {
+		this.content = content;
+	}
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.orm.xml
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.orm.xml?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.orm.xml (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFile.orm.xml Sat Jan 31 16:49:51 2009
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
+    <description>Persistence Metadata for Roller</description>
+    <persistence-unit-metadata>
+        <persistence-unit-defaults>
+            <access>PROPERTY</access>
+        </persistence-unit-defaults>
+    </persistence-unit-metadata>
+    <package>org.apache.roller.weblogger.pojos</package>
+    <entity metadata-complete="true" name="MediaFile"
+            class="org.apache.roller.weblogger.pojos.MediaFile">
+        <table name="media_file"/>
+        <attributes>
+            <id name="id">
+                <column name="id"/>
+            </id>
+            <basic name="name">
+                <column name="name" insertable="true" updatable="true" unique="false" nullable="false"/>
+            </basic>
+            <basic name="description">
+                <column name="description" insertable="true" updatable="true" unique="false" nullable="true"/>
+            </basic>
+            <basic name="contentType">
+                <column name="content_type" insertable="true" updatable="true" unique="false" nullable="false"/>
+            </basic>
+            <basic name="copyrightText">
+                <column name="copyright_text" insertable="true" updatable="true" unique="false" nullable="true"/>
+            </basic>
+            <basic name="length">
+                <column name="size_in_bytes" insertable="true" updatable="true" unique="false" nullable="true"/>
+            </basic>
+            <basic name="dateUploaded">
+                <column name="date_uploaded" insertable="true" updatable="false" unique="false"/>
+            </basic>
+            <basic name="lastUpdated">
+                <column name="last_updated" insertable="true" updatable="true" unique="false"/>
+            </basic>
+            <basic name="sharedForGallery">
+                <column name="is_public" insertable="true" updatable="true" unique="false"/>
+            </basic>
+            <many-to-one name="directory" target-entity="org.apache.roller.weblogger.pojos.MediaFileDirectory">
+                <join-column name="directory_id" insertable="true" updatable="true" nullable="false"/>
+            </many-to-one>
+            <one-to-many name="tags" mapped-by="mediaFile" target-entity="org.apache.roller.weblogger.pojos.MediaFileTag">
+                <cascade>
+                    <cascade-all />
+                </cascade>
+            </one-to-many>
+        </attributes>
+    </entity>
+</entity-mappings>

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.pojos;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.roller.util.UUIDGenerator;
+
+/**
+ * Media file directory.
+ * 
+ */
+public class MediaFileDirectory {
+	
+	String id;
+	String name;
+	String description;
+	MediaFileDirectory parent;
+	Weblog weblog;
+	String path;
+	Set<MediaFileDirectory> childDirectories;
+	Set<MediaFile> mediaFiles;
+	
+	public MediaFileDirectory() {
+    	
+    }
+
+	public MediaFileDirectory(
+            MediaFileDirectory parent,
+            String name,
+            String desc,
+            Weblog weblog) {
+        
+    	this.id = UUIDGenerator.generateUUID();
+    	this.name = name;
+        this.description = desc;
+        
+        this.weblog = weblog;
+        this.parent = parent;
+        
+        // calculate path
+        if(parent == null) {
+            this.path = "/";
+        } else if("/".equals(parent.getPath())) {
+            this.path = "/"+name;
+        } else {
+            this.path = parent.getPath() + "/" + name;
+        }
+    }
+
+    /**
+     * Database surrogate key.
+     *
+     * @roller.wrapPojoMethod type="simple"
+     *
+     * @ejb:persistent-field
+     *
+     * @hibernate.id column="id"
+     *     generator-class="assigned"  
+     */
+	public String getId() {
+		return id;
+	}
+
+    /**
+     * A short name for this folder.
+     *
+     * @roller.wrapPojoMethod type="simple"
+     *
+     * @ejb:persistent-field
+     *
+     * @hibernate.property column="name" non-null="true" unique="false"
+     */
+	public String getName() {
+		return name;
+	}
+
+	/**
+     * @ejb:persistent-field
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+
+    /**
+     * A full description for this folder.
+     *
+     * @roller.wrapPojoMethod type="simple"
+     *
+     * @ejb:persistent-field
+     *
+     * @hibernate.property column="description" unique="false"
+     */
+	public String getDescription() {
+		return description;
+	}
+
+	/**
+     * @ejb:persistent-field
+	 */
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+    /**
+     * Return parent folder, or null if folder is root of hierarchy.
+     *
+     * @roller.wrapPojoMethod type="pojo"
+     *
+     * @ejb:persistent-field
+     *
+     * @hibernate.many-to-one column="parentid" cascade="none" not-null="false"
+     */
+	public MediaFileDirectory getParent() {
+		return parent;
+	}
+
+	/**
+     * @ejb:persistent-field
+	 */
+	public void setParent(MediaFileDirectory parent) {
+		this.parent = parent;
+	}
+
+    /**
+     * Get the weblog which owns this folder.
+     *
+     * @roller.wrapPojoMethod type="pojo"
+     *
+     * @ejb:persistent-field
+     *
+     * @hibernate.many-to-one column="websiteid" cascade="none" not-null="true"
+     */
+	public Weblog getWeblog() {
+		return weblog;
+	}
+
+	/**
+     * @ejb:persistent-field
+	 */
+	public void setWeblog(Weblog weblog) {
+		this.weblog = weblog;
+	}
+
+    /**
+     * The full path to this folder in the hierarchy.
+     *
+     * @roller.wrapPojoMethod type="simple"
+     *
+     * @ejb:persistent-field
+     *
+     * @hibernate.property column="path" non-null="true" unique="false"
+     */
+	public String getPath() {
+		return path;
+	}
+
+	/**
+     * @ejb:persistent-field
+	 */
+	public void setPath(String path) {
+		this.path = path;
+	}
+	
+	
+    /**
+     * Get child folders of this folder.
+     *
+     * @roller.wrapPojoMethod type="pojo-collection" class="org.apache.roller.weblogger.pojos.WeblogBookmarkFolder"
+     *
+     * @hibernate.set lazy="true" inverse="true" cascade="delete" 
+     * @hibernate.collection-key column="parentid"
+     * @hibernate.collection-one-to-many class="org.apache.roller.weblogger.pojos.WeblogBookmarkFolder"
+     */
+    public Set<MediaFileDirectory> getChildDirectories() {
+        return this.childDirectories;
+    }
+    
+    public void setChildDirectories(Set<MediaFileDirectory> folders) {
+        this.childDirectories = folders;
+    }
+    
+    public boolean hasMediaFile(String name) {
+    	Set<MediaFile> fileSet = this.getMediaFiles();
+    	for (MediaFile mediaFile: fileSet) {
+    		if (mediaFile.getName().equals(name)) {
+    			return true;
+    		}
+    	}
+    	return false;
+    }
+    
+    
+    public Set<MediaFile> getMediaFiles() {
+		return mediaFiles;
+	}
+
+	public void setMediaFiles(Set<MediaFile> mediaFiles) {
+		this.mediaFiles = mediaFiles;
+	}
+
+	@Override
+	public boolean equals(Object other) {
+        if (other == this) return true;
+        if (other instanceof MediaFileDirectory != true) return false;
+        MediaFileDirectory o = (MediaFileDirectory)other;
+        return new EqualsBuilder()
+            .append(getId(), o.getId()) 
+            .append(getName(), o.getName()) 
+            .append(getDescription(), o.getDescription()) 
+            .append(getPath(), o.getPath()) 
+            .isEquals();
+	}
+    
+
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileDirectory.orm.xml Sat Jan 31 16:49:51 2009
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
+    <description>Persistence Metadata for Roller</description>
+    <persistence-unit-metadata>
+        <persistence-unit-defaults>
+            <access>PROPERTY</access>
+        </persistence-unit-defaults>
+    </persistence-unit-metadata>
+    <package>org.apache.roller.weblogger.pojos</package>
+    <entity metadata-complete="true" name="MediaFileDirectory"
+            class="org.apache.roller.weblogger.pojos.MediaFileDirectory">
+        <table name="media_file_directory"/>
+        <named-query name="MediaFileDirectory.getByWeblog">
+            <query>SELECT d FROM MediaFileDirectory d WHERE d.weblog = ?1</query>
+        </named-query>
+        <named-query name="MediaFileDirectory.getByWeblogAndNoParent">
+            <query>SELECT d FROM MediaFileDirectory d WHERE d.weblog = ?1 AND d.parent IS NULL</query>
+        </named-query>
+        <attributes>
+            <id name="id">
+                <column name="id"/>
+            </id>
+            <basic name="name">
+                <column name="name" insertable="true" updatable="true" unique="false" nullable="false"/>
+            </basic>
+            <basic name="description">
+                <column name="description" insertable="true" updatable="true" unique="false" nullable="true"/>
+            </basic>
+            <basic name="path">
+                <column name="path" insertable="true" updatable="true" unique="false" nullable="false"/>
+            </basic>
+            <many-to-one name="weblog" target-entity="org.apache.roller.weblogger.pojos.Weblog">
+                <join-column name="websiteid" insertable="true" updatable="true" nullable="false"/>
+            </many-to-one>
+            <many-to-one name="parent" target-entity="org.apache.roller.weblogger.pojos.MediaFileDirectory">
+                <join-column name="parentid" insertable="true" updatable="true" nullable="true"/>
+            </many-to-one>
+            <one-to-many name="childDirectories" mapped-by="parent" target-entity="org.apache.roller.weblogger.pojos.MediaFileDirectory" fetch="LAZY">
+                <order-by>name</order-by>
+                <cascade>
+                    <cascade-remove/>
+                </cascade>
+            </one-to-many>
+            <one-to-many name="mediaFiles" mapped-by="directory" target-entity="org.apache.roller.weblogger.pojos.MediaFile" fetch="LAZY">
+                <order-by>name</order-by>
+                <cascade>
+                    <cascade-all/>
+                </cascade>
+            </one-to-many>
+        </attributes>
+    </entity>
+</entity-mappings>

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.pojos;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+
+import org.apache.roller.util.UUIDGenerator;
+
+@Entity
+@Table (name="media_file_tag")
+@NamedQuery (
+		name="MediaFileTag.getByMediaFile",
+		query="SELECT w FROM MediaFileTag w WHERE w.mediaFile = ?1")
+public class MediaFileTag {
+	
+	@Id
+	String id = UUIDGenerator.generateUUID();
+	
+	//@Column "name"
+	String name;
+	MediaFile mediaFile;
+	
+	public MediaFileTag() {
+	}
+
+	public MediaFileTag(String name, MediaFile mediaFile) {
+		this.name = name;
+		this.mediaFile = mediaFile;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public MediaFile getMediaFile() {
+		return mediaFile;
+	}
+
+	public void setMediaFile(MediaFile mediaFile) {
+		this.mediaFile = mediaFile;
+	}
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.orm.xml
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.orm.xml?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.orm.xml (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/pojos/MediaFileTag.orm.xml Sat Jan 31 16:49:51 2009
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings version="1.0" xmlns="http://java.sun.com/xml/ns/persistence/orm"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
+    <description>Persistence Metadata for Roller</description>
+    <persistence-unit-metadata>
+        <persistence-unit-defaults>
+            <access>PROPERTY</access>
+        </persistence-unit-defaults>
+    </persistence-unit-metadata>
+    <package>org.apache.roller.weblogger.pojos</package>
+    <entity metadata-complete="true" name="MediaFileTag"
+            class="org.apache.roller.weblogger.pojos.MediaFileTag">
+        <table name="media_file_tag"/>
+        <named-query name="MediaFileTag.getByMediaFile">
+            <query>SELECT w FROM MediaFileTag w WHERE w.mediaFile = ?1</query>
+        </named-query>
+        <attributes>
+            <id name="id">
+                <column name="id"/>
+            </id>
+            <basic name="name">
+                <column name="name" insertable="true" updatable="true" unique="false" nullable="false"/>
+            </basic>
+            <many-to-one name="mediaFile" target-entity="org.apache.roller.weblogger.pojos.MediaFile">
+                <join-column name="media_file_id" insertable="true" updatable="true" nullable="false"/>
+            </many-to-one>
+        </attributes>
+    </entity>
+</entity-mappings>

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/rendering/servlets/MediaResourceServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/rendering/servlets/MediaResourceServlet.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/rendering/servlets/MediaResourceServlet.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/rendering/servlets/MediaResourceServlet.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.ui.rendering.servlets;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.weblogger.business.MediaFileManager;
+import org.apache.roller.weblogger.business.WebloggerFactory;
+import org.apache.roller.weblogger.pojos.MediaFile;
+import org.apache.roller.weblogger.pojos.Weblog;
+import org.apache.roller.weblogger.ui.rendering.util.ModDateHeaderUtil;
+
+
+// TODO: Ganesh - update documentation
+/**
+ * Serves media files uploaded by users.
+ *
+ * Since we keep resources in a location outside of the webapp
+ * context we need a way to serve them up.  This servlet assumes that
+ * resources are stored on a filesystem in the "uploads.dir" directory.
+ *
+ * @web.servlet name="ResourcesServlet" load-on-startup="5"
+ * @web.servlet-mapping url-pattern="/roller-ui/rendering/resources/*"
+ */
+public class MediaResourceServlet extends HttpServlet {
+
+    private static Log log = LogFactory.getLog(MediaResourceServlet.class);
+    
+    public void init(ServletConfig config) throws ServletException {
+
+        super.init(config);
+        log.info("Initializing ResourceServlet");
+        
+    }
+
+
+    /**
+     * Handles requests for user uploaded resources.
+     */
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        
+        MediaFileManager mfMgr = WebloggerFactory.getWeblogger().getMediaFileManager();
+
+        String fileId = request.getPathInfo();
+        
+        log.debug("parsing file id -  " + fileId);
+        
+        // first, cleanup extra slashes and extract the weblog weblogHandle
+        if(fileId != null && fileId.trim().length() > 1) {
+            
+            // strip off the leading slash
+        	fileId = fileId.substring(1);
+            
+            // strip off trailing slash if needed
+            if(fileId.endsWith("/")) {
+            	fileId = fileId.substring(0, fileId.length() - 1);
+            }
+        }
+
+        log.debug("File requested [" + fileId + "]");
+    
+        long resourceLastMod = 0;
+        InputStream resourceStream = null;
+        MediaFile mediaFile = null;
+        
+        try {
+            mediaFile = mfMgr.getMediaFile(fileId, true);
+            resourceLastMod = mediaFile.getLastModified();
+        } catch (Exception ex) {
+            // still not found? then we don't have it, 404.
+            log.debug("Unable to get resource", ex);
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        // Respond with 304 Not Modified if it is not modified.
+        if (ModDateHeaderUtil.respondIfNotModified(request, response, resourceLastMod)) {
+            return;
+        } else {
+            // set last-modified date
+            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod);
+        }
+        
+
+        // set the content type based on whatever is in our web.xml mime defs
+        response.setContentType(mediaFile.getContentType());
+        resourceStream = mediaFile.getInputStream();
+        
+        OutputStream out = null;
+        try {
+            // ok, lets serve up the file
+            byte[] buf = new byte[8192];
+            int length = 0;
+            out = response.getOutputStream();
+            while((length = resourceStream.read(buf)) > 0) {
+                out.write(buf, 0, length);
+            }
+            
+            // close output stream
+            out.close();
+            
+        } catch (Exception ex) {
+            if(!response.isCommitted()) {
+                response.reset();
+                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            }
+        } finally {
+            // make sure stream to resource file is closed
+            resourceStream.close();
+        }
+
+    }
+
+}

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd-validation.xml
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd-validation.xml?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd-validation.xml (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd-validation.xml Sat Jan 31 16:49:51 2009
@@ -0,0 +1,23 @@
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+       "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+    
+    <field name="bean.name">
+        <field-validator type="requiredstring">
+            <message key="MediaFile.error.nameNull">unspecified key</message>
+        </field-validator>
+        
+        <field-validator type="stringlength">
+            <param name="maxLength">255</param>
+            <message key="MediaFile.error.nameSize">unspecified key</message>
+        </field-validator>
+    </field>
+    
+    <field name="bean.description">
+        <field-validator type="stringlength">
+            <param name="maxLength">255</param>
+            <message key="MediaFile.error.descriptionSize">unspecified key</message>
+        </field-validator>
+    </field>
+    
+</validators>

Added: roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java?rev=739576&view=auto
==============================================================================
--- roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java (added)
+++ roller/branches/roller_mediablogging/apps/weblogger/src/java/org/apache/roller/weblogger/ui/struts2/editor/MediaFileAdd.java Sat Jan 31 16:49:51 2009
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.roller.weblogger.ui.struts2.editor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.weblogger.WebloggerException;
+import org.apache.roller.weblogger.business.FileIOException;
+import org.apache.roller.weblogger.business.MediaFileManager;
+import org.apache.roller.weblogger.business.WebloggerFactory;
+import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
+import org.apache.roller.weblogger.pojos.MediaFile;
+import org.apache.roller.weblogger.pojos.MediaFileDirectory;
+import org.apache.roller.weblogger.ui.struts2.util.UIAction;
+import org.apache.struts2.interceptor.validation.SkipValidation;
+
+/**
+ * Adds a new media file.
+ */
+@SuppressWarnings("serial")
+public class MediaFileAdd extends UIAction {
+    private static Log log = LogFactory.getLog(MediaFileAdd.class);
+    
+    private MediaFileBean bean =  new MediaFileBean();
+    private String directoryId;
+    private MediaFileDirectory directory;
+    private List<MediaFileDirectory> allDirectories;
+
+    // file uploaded by the user
+    private File uploadedFile = null;
+    
+    // content type for upload file
+    private String uploadedFileContentType = null;
+    
+    // filename for uploaded file
+    private String uploadedFileFileName = null;
+
+    public MediaFileAdd() {
+        this.actionName = "mediaFileAdd";
+        this.desiredMenu = "editor";
+        this.pageTitle = "mediaFile.add.title";
+    }
+    
+    public void myPrepare() {
+        try {
+            MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager();
+            setAllDirectories(mgr.getMediaFileDirectories(getActionWeblog()));
+            if(!StringUtils.isEmpty(getDirectoryId())) {
+                setDirectory(mgr.getMediaFileDirectory(getDirectoryId()));
+            }
+            else {
+                setDirectory(mgr.createRootMediaFileDirectory(getActionWeblog()));
+            }
+        } catch (WebloggerException ex) {
+            log.error("Error looking up media file directory", ex);
+            // TODO: Ganesh - Handle exception
+        }
+    }
+
+    /**
+     * Show form for adding a new media file.
+     * 
+     * @return String The result of the action.
+     */
+    @SkipValidation
+    public String execute() {
+		return INPUT;
+    }
+    
+    /**
+     * Save a media file.
+     * 
+     * @return String The result of the action.
+     */
+    public String save() {
+    	myValidate();
+    	if (!hasActionErrors()) {
+    		MediaFileManager manager = WebloggerFactory.getWeblogger().getMediaFileManager();
+    		try {
+    			MediaFile mediaFile = new MediaFile();
+    			bean.copyTo(mediaFile);
+    			mediaFile.setDirectory(getDirectory());
+    			mediaFile.setLength(this.uploadedFile.length());
+    			mediaFile.setInputStream(new FileInputStream(this.uploadedFile));
+    			mediaFile.setContentType(this.uploadedFileContentType);
+				manager.createMediaFile(getActionWeblog(), mediaFile);
+	            WebloggerFactory.getWeblogger().flush();
+	            bean.setId(mediaFile.getId());
+	    		return SUCCESS;
+            } catch (FileIOException ex) {
+                addError("uploadFiles.error.upload", bean.getName());
+			} catch (Exception e) {
+	            log.error("Error saving new entry", e);
+                // TODO: i18n
+                addError("Error reading uploaded file - " + bean.getName());
+			}
+			
+    	}
+		return INPUT;
+    }
+    
+    public void myValidate() {
+        if (getDirectory().hasMediaFile(getBean().getName())) {
+            addError("MediaFile.error.duplicateName", getBean().getName());
+        }
+        // make sure uploads are enabled
+        if(!WebloggerRuntimeConfig.getBooleanProperty("uploads.enabled")) {
+            addError("error.upload.disabled");
+        }
+        
+        if (StringUtils.isEmpty(this.uploadedFileFileName)) {
+        	addError("error.upload.file");
+        }
+    }
+    
+    /**
+     * Get the list of all categories for the action weblog, not including root.
+     */
+    public List<MediaFileDirectory> getDirectories() {
+        try {
+        	MediaFileManager mgr = WebloggerFactory.getWeblogger().getMediaFileManager();
+            return mgr.getMediaFileDirectories(getActionWeblog());
+        } catch (WebloggerException ex) {
+            log.error("Error getting media file directory list for weblog - "+getWeblog(), ex);
+            return Collections.EMPTY_LIST;
+        }
+    }
+
+    public MediaFileBean getBean() {
+    	return bean;
+    }
+    
+    public void setBean(MediaFileBean b) {
+    	this.bean = b;
+    }
+    
+	public String getDirectoryId() {
+		return directoryId;
+	}
+
+	public void setDirectoryId(String id) {
+		this.directoryId = id;
+	}
+
+	public MediaFileDirectory getDirectory() {
+		return directory;
+	}
+
+	public void setDirectory(MediaFileDirectory directory) {
+		this.directory = directory;
+	}
+	
+	public List<MediaFileDirectory> getAllDirectories() {
+		return allDirectories;
+	}
+    
+	public void setAllDirectories(List<MediaFileDirectory> dirs) {
+		this.allDirectories = dirs;
+	}
+
+    public File getUploadedFile() {
+        return uploadedFile;
+    }
+
+    public void setUploadedFile(File uploadedFile) {
+        this.uploadedFile = uploadedFile;
+    }
+
+    public String getUploadedFileContentType() {
+        return uploadedFileContentType;
+    }
+
+    public void setUploadedFileContentType(String uploadedFileContentType) {
+        this.uploadedFileContentType = uploadedFileContentType;
+    }
+
+    public String getUploadedFileFileName() {
+        return uploadedFileFileName;
+    }
+
+    public void setUploadedFileFileName(String uploadedFileFileName) {
+        this.uploadedFileFileName = uploadedFileFileName;
+    }
+    
+    public boolean isContentTypeImage() {
+    	// TODO: To be expanded
+    	if ("image/jpeg".equals(this.uploadedFileContentType)
+    	|| 	"image/gif".equals(this.uploadedFileContentType)	
+    	) {
+    		return true;
+    	}
+    	
+    	return false;
+    }
+}



Mime
View raw message