/**
- * Interfacedefinition für Datenbank-Adpatoren. Die Adaptoren legen
- * jeweils das Verhalten und die Befehlsmächtigkeit der Datenbank
- * fest.
+ * Handles audio media, like mp3 and maybe it could also handle some other.
+ * It is MediaHandlerGeneric with different icons.
*
- * @author <mh>
+ * @see mir.media.MediaHandlerGeneric
+ * @see mir.media.MirMedia
+ * @author mh <heckmann@hbe.ca>
* @version 24.09.2001
*/
/**
- * Interfacedefinition für Datenbank-Adpatoren. Die Adaptoren legen
- * jeweils das Verhalten und die Befehlsmächtigkeit der Datenbank
- * fest.
+ * This is the Generic MediaHandler. It stores the media data on
+ * the filesystem and keeps basic metadata (size, type...) in the
+ * DB. Usually only representation needs to be overridden.
+ * See the MediaHandlerAudio class to see an example of how one
+ * could override it.
+ * <p>
+ * Most media handlers should override this class.
+ * <p>
+ * In theory, it could be used to handle miscellaneous media that
+ * we don't have entered in the media_type table, (like RTF documents,
+ * PS, PDF, etc..)
+ * <p>
+ * Of course it implements the MirMedia interface.
*
- * @author <mh>
+ * @see mir.media.MirMedia
+ * @author mh <heckmann@hbe.ca>
* @version 24.09.2001
*/
/**
* This class handles saving, fetching creating representations
- * for all images.
- *
+ * for all images. The image content is stored in the DB. The content is
+ * written out to a file at the ProducerImages level.
+ * Remember that Handlers for specific image types, Gif, Jpeg, etc..
+ * should override it.
+ * It implements the MirMedia interface.
+ * <p>
* ok. this is a big hack, it's cause putting the image in the DB
* and fetching it from the DB needs low level db connections for
- * some reason. -mh 25.09.2001
+ * some reason. Does anyone know how to get around this?
+ * -mh 25.09.2001
*
+ * @see mir.media.MirMedia
* @author mh
* @version 24.09.2001
*/
/**
* This class handles saving, fetching creating representations
- * for gif images.
+ * for gif images. it overrides MediaHandlerImages.
*
+ * @see mir.media.MediaHandlerImages
+ * @see mir.media.MirMedia
* @author mh
* @version 24.09.2001
*/
/**
* This class handles saving, fetching creating representations
- * for jpeg images.
+ * for jpeg images. it overrides MediaHandlerImages.
*
+ * @see mir.media.MediaHandlerImages
+ * @see mir.media.MirMedia
* @author mh <heckmann@hbe.ca>
* @version 24.09.2001
*/
/*
* put your module comment here
+ *
*/
import mir.entity.*;
/**
- * Interfacedefinition für Datenbank-Adpatoren. Die Adaptoren legen
- * jeweils das Verhalten und die Befehlsmächtigkeit der Datenbank
- * fest.
- *
- * @author <mh>
+ * Interface for Media handling in Mir. All media handlers
+ * must implement this interface. Each specific media type,
+ * be it Gif, Jpeg, Mp3 audio, Real Audio or quicktime video
+ * has special needs when it comes to representation on the various
+ * pages (article, list, summary), must be stored differently and has a
+ * different URL, etc... This interface allows Mir to support
+ * an infinite (I hope) number of media types. Once this is done,
+ * no code at any other level in Mir needs to be changed other than
+ * adding the content-type <-> media handler name mapping in the
+ * media_type table. The following is an example of the media_type
+ * table:
+ * <p>
+ * id | name | mime_type | classname | tablename | dcname<br>
+ *---+---------+--------------------------+-----------+---------------+-------<br>
+ * 2 | unknown | application/octet-stream | -- | UploadedMedia | <br>
+ * 3 | jpg | image/gif | ImagesGif | Images | <br>
+ * 4 | mp3 | audio/mp3 | Audio | UploadedMedia | <br>
+ * <p>
+ * The "id" field is used as a mapping in the table that contains the media type
+ * to the media_type table. For example, the images table has a to_media_type
+ * field that contains the id in the media_type table.
+ * <p>
+ * The "name" field is used for various display/filenaming purposes. it should
+ * match a valid file extension name for a media_type (we could have used the
+ * content-type map for this....).
+ * <p>
+ * The "mime_type" field is the most important as it does maps the type to Java
+ * classes (the storage and media_handler name). We call those classes using
+ * reflection. This way, once a Handler for a specific media type is implemented
+ * and entered into the media_type table, no other Mir code needs to be modified.
+ * <p>
+ * The "classname" field is the name of the media handler (e.g MediaHandlerAudio)
+ * we use it to call the MediaHandler methods via reflection.
+ * <p>
+ * The "tablename" is the name of the database storage classes (e.g DatabaseImages
+ * and EntityImages). We use this to fetch/storage the media (meta)data in the db.
+ * <p?
+ * The "dcname" field is as of yet unused. Do search for "Dublin Core" on google
+ * to learn more.
+ * <p>
+ * Most media handlers should just extend MediaHandlerGeneric (i.e inherit from
+ * ) and just override the things that need to be specific. see MediaHandlerAudio
+ *
+ * @author mh <heckmann@hbe.ca>
* @version 24.09.2001
*/
public interface MirMedia{
- /* Liefert den Namen der Adaptorklasse
- * @return Adaptorklasse als String
- */
+ /**
+ * Takes the uploaded media data itself, along with the media Entity
+ * which contains the Media metadata plus the MediaType entity containing
+ * all the info for the specific media type itself. It's job is store the
+ * Media data (content) itself, this could be on the local filesystem, in the
+ * DB or even on a remote host. It then inserts the MetaData in the DB.
+ * @param uploadedData, a byte array containing the uploaded data.
+ * @param ent, an Entity holding the media MetaData
+ * @param mediaType, an Entity holding the media_table entry
+ * @return boolean, success/fail
+ * @see mir.entity.Entity
+ */
public abstract boolean set (byte[] uploadedData, Entity ent, Entity mediaTypeEnt );
+
+ /**
+ * Get's the media data from storage and returns it as a byte array
+ * Not very useful for most media types as they are stored in a file,
+ * but very usefull for ones stored in the DB as it is necessary to get
+ * it first before making a file out of it (in Producer*).
+ * @param ent, an Entity holding the media MetaData
+ * @param mediaType, an Entity holding the media_table entry
+ * @return byte[]
+ * @see mir.entity.Entity
+ */
public abstract byte[] get (Entity ent, Entity mediaTypeEnt);
+
+ /**
+ * Pretty much like get() above. But get's the specific Icon
+ * representation. useful for media stored in the DB.
+ * @param ent, an Entity holding the media MetaData
+ * @return byte[]
+ * @see mir.entity.Entity
+ */
public abstract byte[] getIcon (Entity ent);
- public abstract String getURL (Entity ent, Entity mediaTypeEnt);
- public abstract String getListView (Entity ent, Entity mediaTypeEnt);
- public abstract String getStoragePath ();
+
+ /**
+ * gets the final content representation for the media
+ * in the form of a URL (String) that allows someone to
+ * download, look at or listen to the media. (HREF, img src
+ * streaming link, etc..)
+ * It should use the helper functions in the StringUtil class to
+ * build URL's safely, eliminating any *illegal* user input.
+ * @param ent, an Entity holding the media MetaData
+ * @param mediaTypeEnt, an Entity holding the media_table entry
+ * @return String, the url.
+ * @see mir.entity.Entity
+ * @see mir.misc.StringUtil
+ */
+ public abstract String getURL (Entity ent, Entity mediaTypeEnt);
+
+ /**
+ * gets the summary representation for the media
+ * in the form of a URL (String). Usually the URL points
+ * to some sort of an icon that previews what kind of
+ * media an article will contain.
+ * It should use the helper functions in the StringUtil class to
+ * build URL's safely, eliminating any *illegal* user input.
+ * @param ent, an Entity holding the media MetaData
+ * @param mediaTypeEnt, an Entity holding the media_table entry
+ * @return String, the url.
+ * @see mir.entity.Entity
+ * @see mir.misc.StringUtil
+ */
+ public abstract String getListView (Entity ent, Entity mediaTypeEnt);
+
+ /**
+ * Returns the absolute filesystem path to where the media
+ * content should be stored. This path is usually defined
+ * in the configuration wich is accessible through the MirConfig
+ * class.
+ * @return String, the path.
+ * @see mir.misc.MirConfig
+ */
+ public abstract String getStoragePath ();
+
+ /**
+ * Returns the *relative* filesystem path to where the media
+ * icon content should be stored. It is relative to the path
+ * returned by getStoragePath()
+ * This path is usually defined
+ * in the configuration wich is accessible through the MirConfig
+ * class.
+ * @return String, the path.
+ * @see mir.misc.MirConfig
+ */
public abstract String getIconStoragePath ();
+
+ /**
+ * Returns the base URL to that the media is accessible from
+ * to the end user. This could be a URL to another host.
+ * This is used in the Metadata stored in the DB and later on
+ * ,the templates use it.
+ * It is usually defined
+ * in the configuration wich is accessible through the MirConfig
+ * class.
+ * @return String, the base URL to the host.
+ * @see mir.misc.MirConfig
+ */
public abstract String getPublishHost ();
+
+ /**
+ * Returns the file name of the Icon representing the media type.
+ * It is used in the summary view.
+ * It is usually defined
+ * in the configuration wich is accessible through the MirConfig
+ * class.
+ * @return String, the icon filename.
+ * @see mir.misc.MirConfig
+ */
public abstract String getBigIcon ();
+
+ /**
+ * Returns the file name of the small Icon representing
+ * the media type.
+ * It is used in the right hand newswire list of the startpage.
+ * It is usually defined
+ * in the configuration wich is accessible through the MirConfig
+ * class.
+ * @return String, the icon filename.
+ * @see mir.misc.MirConfig
+ */
public abstract String getTinyIcon ();
+
+ /**
+ * Returns the IMG SRC "ALT" text to be used
+ * for the Icon representations
+ * @return String, the ALT text.
+ */
public abstract String getIconAlt ();
- public abstract boolean isVideo ();
+
+ /**
+ * your all smart enough to figure it out.
+ * @return boolean.
+ */
+ public abstract boolean isVideo ();
+
+ /**
+ * your all smart enough to figure it out.
+ * @return boolean.
+ */
public abstract boolean isAudio ();
+
+ /**
+ * your all smart enough to figure it out.
+ * @return boolean.
+ */
public abstract boolean isImage ();
}
SimpleList parentList = HTMLTemplateProcessor.makeSimpleList(theParentList);
// get the newswire
- whereClause="is_published=true AND to_article_type >= 1";
+ whereClause="is_published=true AND to_article_type = 1";
entityList = contentModule.getContent(whereClause,"date desc, webdb_create desc",0,newsPerPage);
SimpleList newsWireList = HTMLTemplateProcessor.makeSimpleList(entityList);
for (int i=0; i < entityList.size();i++) {
SimpleList startItemList = HTMLTemplateProcessor.makeSimpleList(entityList);
for (int k=0; k < entityList.size();k++) {
currentContent = (EntityContent)entityList.elementAt(k);
- //images to content
+ //media to content
currentMediaList = DatabaseContentToMedia.getInstance().getUploadedMedia(currentContent);
if (currentMediaList!=null && currentMediaList.getCount()>=1) {
SimpleList mediaListAudio = new SimpleList();
SimpleList mediaListImages = new SimpleList();
SimpleList mediaListVideo = new SimpleList();
SimpleList mediaListOther = new SimpleList();
- //SimpleHash allMediaSimpleHash = new SimpleHash();
for (int n=0; n < currentMediaList.size();n++) {
upMedia = currentMediaList.elementAt(n);
upMediaSimpleHash = HTMLTemplateProcessor.makeSimpleHash(upMedia);
} //end if media_type != null
} //end for
try{
- //SimpleList contentList = (SimpleList)mergeData.get("contentlist");
contentHash = (SimpleHash)startItemList.get(k);
contentHash.put("to_media_audio", mediaListAudio);
contentHash.put("to_media_images", mediaListImages);
} //end if currentMediaList != null
} //enf for featurueList.size..
-
-
- /*for (int i=0; i < entityList.size();i++) {
- currentContent = (EntityContent)entityList.elementAt(i);
- //fetching/setting the images
- imageEntityList = DatabaseContentToMedia.getInstance().getImages(currentContent);
- if (imageEntityList!=null && imageEntityList.getCount()>=1) {
- try{
- mediaList = HTMLTemplateProcessor.makeSimpleList(imageEntityList);
- contentHash = (SimpleHash)startItemList.get(i);
- contentHash.put("to_media", mediaList);
- } catch (Exception e){}
- }
- }*/
-
// get the breaking news
// only the first 5
// todo: the number of breaking_news items have to be configurable
SimpleList featureList = HTMLTemplateProcessor.makeSimpleList(entityList);
for (int k=0; k < entityList.size();k++) {
currentContent = (EntityContent)entityList.elementAt(k);
- //images to content
+ //media to content
currentMediaList = DatabaseContentToMedia.getInstance().getUploadedMedia(currentContent);
if (currentMediaList!=null && currentMediaList.getCount()>=1) {
SimpleList mediaListAudio = new SimpleList();
SimpleList mediaListImages = new SimpleList();
SimpleList mediaListVideo = new SimpleList();
SimpleList mediaListOther = new SimpleList();
- //SimpleHash allMediaSimpleHash = new SimpleHash();
for (int n=0; n < currentMediaList.size();n++) {
upMedia = currentMediaList.elementAt(n);
upMediaSimpleHash = HTMLTemplateProcessor.makeSimpleHash(upMedia);
} //end if media_type != null
} //end for
try{
- //SimpleList contentList = (SimpleList)mergeData.get("contentlist");
contentHash = (SimpleHash)featureList.get(k);
contentHash.put("to_media_audio", mediaListAudio);
contentHash.put("to_media_images", mediaListImages);
} //end if currentMediaList != null
} //enf for featurueList.size..
-
-
- /*for (int i=0; i < entityList.size();i++) {
- currentContent = (EntityContent)entityList.elementAt(i);
- //fetching/setting the images
- imageEntityList = DatabaseContentToMedia.getInstance().getImages(currentContent);
- if (imageEntityList!=null && imageEntityList.getCount()>=1) {
- try{
- mediaList = HTMLTemplateProcessor.makeSimpleList(imageEntityList);
- contentHash = (SimpleHash)featureList.get(i);
- contentHash.put("to_media", mediaList);
- } catch (Exception e){}
- }
- }*/
-
// Zusaetzlich Informationen
startPageModel = new SimpleHash();
startPageModel.put("breakingnews", breakingList);
import java.io.*;
import java.lang.*;
+import java.lang.reflect.*;
import java.util.*;
import java.sql.*;
import freemarker.template.*;
import mir.misc.*;
+import mir.media.*;
import mir.storage.*;
import mir.module.*;
import mir.entity.*;
public class ProducerTopics extends ProducerList {
public String where;
+ String currentMediaId;
+ EntityList upMediaEntityList;
+ EntityList imageEntityList;
+ EntityList currentMediaList;
+ Entity mediaType;
+ EntityMedia uploadedMedia;
+ Class mediaHandlerClass=null;
+ MirMedia mediaHandler=null;
+ String mediaHandlerName=null;
+ Database mediaStorage=null;
+ String tinyIcon;
+ String iconAlt;
public void setAdditional(String key, TemplateModel value) {
additional.put(key,value);
if(entityList != null && entityList.size()==1){
currentContent = (EntityContent)entityList.elementAt(0);
SimpleHash specialHash = HTMLTemplateProcessor.makeSimpleHash(currentContent);
- // get the images
- EntityList currentMedia = DatabaseContentToMedia.getInstance().getImages(currentContent);
- if (currentMedia!=null && currentMedia.getCount()>=1) {
- SimpleList mediaList = HTMLTemplateProcessor.makeSimpleList(currentMedia);
- specialHash.put("to_media",mediaList);
- }
+
+ currentMediaList = DatabaseContentToMedia.getInstance().getUploadedMedia(currentContent);
+ if (currentMediaList!=null && currentMediaList.getCount()>=1) {
+ SimpleList mediaListAudio = new SimpleList();
+ SimpleList mediaListImages = new SimpleList();
+ SimpleList mediaListVideo = new SimpleList();
+ SimpleList mediaListOther = new SimpleList();
+ for (int n=0; n < currentMediaList.size();n++) {
+ upMedia = currentMediaList.elementAt(n);
+ upMediaSimpleHash = HTMLTemplateProcessor.makeSimpleHash(upMedia);
+ mediaType = ((EntityMedia)upMedia).getMediaType();
+ //must be a non-existant to_media_type entry..
+ if (mediaType != null) {
+ try {
+ mediaHandlerName = mediaType.getValue("classname");
+ mediaStorageName = mediaType.getValue("tablename");
+ mediaStorageClass = Class.forName("mircoders.storage.Database"+mediaStorageName);
+ mediaHandlerClass = Class.forName("mir.media.MediaHandler"+mediaHandlerName);
+ mediaHandler = (MirMedia)mediaHandlerClass.newInstance();
+ Method m = mediaStorageClass.getMethod("getInstance", null);
+ mediaStorage = (Database)m.invoke(null, null);
+ //we most likely need further info
+ upMedia = mediaStorage.selectById(upMedia.getId());
+ } catch (Exception e) {
+ theLog.printError("ProducerList: problem in reflection: "+mediaHandlerName);
+ } //end catch
+ upMediaSimpleHash.put("url", mediaHandler.getListView(upMedia, mediaType));
+ if (upMedia.getValue("is_published") == "1") {
+ if (mediaHandler.isImage()) {
+ mediaListImages.add(upMediaSimpleHash);
+ } else if (mediaHandler.isAudio()) {
+ mediaListAudio.add(upMediaSimpleHash);
+ } else if (mediaHandler.isVideo()) {
+ mediaListVideo.add(upMediaSimpleHash);
+ } else {
+ mediaListOther.add(upMediaSimpleHash);
+ }
+ } //end if is_published
+ } //end if media_type != null
+ } //end for
+ try{
+ specialHash.put("to_media_audio", mediaListAudio);
+ specialHash.put("to_media_images", mediaListImages);
+ specialHash.put("to_media_video", mediaListVideo);
+ specialHash.put("to_media_other", mediaListOther);
+ } catch (Exception e){}
+ } //end if currentMediaList != null
setAdditional("special",specialHash);
}
for(Iterator it = mp.requestList.iterator(); it.hasNext();){
MpRequest mpReq = (MpRequest)it.next();
String fileName = mpReq.getFilename();
+ //This is just a temporary way to get the content-type via
+ //the .extension , we need to use a magic method, by looking
+ //at the header (first few bytes) of the file. -mh
+ //the Oreilly method sucks cause it rely's on the what
+ //content-type the client browser sends and that's
+ //too often application-octet stream.
String contentType = FileUtil.guessContentTypeFromName(fileName);
HashMap mediaValues = new HashMap();
theLog.printError("CONTENT TYPE IS: "+contentType);
-
+
+ //The map file should be Mir/content-types.properties, it's the
+ //default Sun Java file+ some entries that it did not have.
+ //so if you support a new media type you have to make sure that
+ //it is in this file
if ((contentType==null) || (contentType=="application/octet-stream")) {
throw new ServletModuleException("ModuleException: One or more files of unrecognized types");
}
-
String mediaTitle=(String)withValues.get("media_title"+i);
i++;
mediaValues.put("is_produced", "0");
mediaValues.put("is_published","1");
+ //the where clause to find the media_type entry
+ //from the content-type.
+ //we use the media type entry to lookup the
+ //media Handler/Storage classes
String wc = " mime_type='"+contentType+"'";
EntityList mediaTypesList = DatabaseMediaType.getInstance().selectByWhereClause(wc);
String mediaTypeId = null;
String mediaStorageName = null;
String mediaHandlerName = null;
-
+
+ //if we found an entry matching the
+ //content-type int the table.
if (mediaTypesList.size() > 0) {
+ //get the class names from the media_type table.
mediaTypeId = mediaTypesList.elementAt(0).getId();
mediaStorageName = mediaTypesList.elementAt(0).getValue("tablename");
mediaHandlerName = mediaTypesList.elementAt(0).getValue("classname");
mediaValues.put("to_media_type",mediaTypeId);
-
+
+ //load the classes via reflection
String MediaId;
try {
Class mediaStorageClass = Class.forName("mircoders.storage.Database"+mediaStorageName);
Class mediaHandlerClass = Class.forName("mir.media.MediaHandler"+mediaHandlerName);
MirMedia mediaHandler = (MirMedia)mediaHandlerClass.newInstance();
+ //save and store the media data/metadata
mediaHandler.set(mpReq.getMedia(), mediaEnt,mediaTypesList.elementAt(0));
//were done with mpReq at this point, dereference it. as it contains
//mucho mem. -mh 01.10.2001
mpReq=null;
-
+
if(mediaId!=null){
new ProducerMedia().handle(null, null, false, false, mediaId);
}
theLog.printError("setting uploaded_media failed: "+e.toString());
} //end try-catch
-
+ //we got this far, associate the media to the article
try{
DatabaseContentToMedia.getInstance().addMedia(cid,mediaId);
theLog.printError("setting content_x_media success");
<td>
<h3>${special.title}</h3>
<h4><i>${special.creator}, ${special.webdb_create_formatted}</i></h4>
- <p> <if special.to_media && special.to_media[0]["is_published"]=="1">
- <img src="${special.to_media[0]["icon_path"]}" width="${special.to_media[0]["icon_width"]}" height="${special.to_media[0]["icon_height"]}" alt="" align="left" vspace="8" hspace="8">
- </if> ${special.description} </p>
+ <p>
+ <if special.to_media_audio && special.to_media_audio[0]["is_published"]=="1">
+ ${special.to_media_audio[0]["url"]}
+ </if>
+ <if special.to_media_video && special.to_media_video[0]["is_published"]=="1">
+ ${special.to_media_video[0]["url"]}
+ </if>
+ <if special.to_media_other && special.to_media_other[0]["is_published"]=="1">
+ ${special.to_media_other[0]["url"]}
+ </if>
+ <p>
+ <if special.to_media_images && special.to_media_images[0]["is_published"]=="1">
+ ${special.to_media_images[0]["url"]}
+ </if>
+ ${special.description} </p>
<p align="right">[<a href="${config.docroot}${special.publish_path}${special.id}.shtml">read</a>]</p>
</td>
</tr>
<h3>${i.title}</h3>
<h4><i>${i.creator}, ${i.webdb_create_formatted}</i></h4>
<p>
- <if i.to_media && i.to_media[0]["is_published"]=="1">
- <img src="${i.to_media[0]["icon_path"]}" width="${i.to_media[0]["icon_width"]}" height="${i.to_media[0]["icon_height"]}" alt="" align="left" vspace="8" hspace="8">
- </if>
+ <if i.to_media_audio && i.to_media_audio[0]["is_published"]=="1">
+ ${i.to_media_audio[0]["url"]}
+ </if>
+ <if i.to_media_video && i.to_media_video[0]["is_published"]=="1">
+ ${i.to_media_video[0]["url"]}
+ </if>
+ <if i.to_media_other && i.to_media_other[0]["is_published"]=="1">
+ ${i.to_media_other[0]["url"]}
+ </if>
+ <p>
+ <if i.to_media_images && i.to_media_images[0]["is_published"]=="1">
+ ${i.to_media_images[0]["url"]}
+ </if>
${i.description}</p>
<p align="right">[<a href="${config.docroot}${i.publish_path}${i.id}.shtml">read</a>]</p>
</td>