1.1 restoration
authorzapata <zapata>
Sun, 21 Nov 2004 22:07:12 +0000 (22:07 +0000)
committerzapata <zapata>
Sun, 21 Nov 2004 22:07:12 +0000 (22:07 +0000)
322 files changed:
build.xml
bundles/admin_en.properties
bundles/admin_es.properties
bundles/admin_eu.properties
bundles/admin_ro.properties [new file with mode: 0755]
dbscripts/help_arttype.sql
dbscripts/help_lang.sql
doc/CODESTRUCTURE [deleted file]
doc/CODINGSTYLE [deleted file]
doc/DC.txt [deleted file]
doc/INSTALL.mir [deleted file]
doc/INTERNATIONALIZATION.howto [deleted file]
doc/KNOWN_BUGS [deleted file]
doc/LOCALIZER.HOWTO [deleted file]
doc/LONG.INSTALL.mir [deleted file]
doc/README [deleted file]
doc/README.jikes [deleted file]
doc/TODO.txt [deleted file]
doc/UPGRADING.mir [deleted file]
doc/mission.html
etc/bundles/adminlocal.properties
etc/bundles/open_en.properties
etc/config.properties-dist
etc/content-types.properties [deleted file]
etc/extralib/README [new file with mode: 0755]
etc/log4j.properties
etc/open/comment.template [deleted file]
etc/open/comment_done.template [deleted file]
etc/open/comment_dupe.template [deleted file]
etc/open/donetranslation.template [new file with mode: 0755]
etc/open/editarticle.template
etc/open/editcomment.template
etc/open/edittranslation.template [new file with mode: 0755]
etc/open/error.template
etc/open/posting.template [deleted file]
etc/open/posting_done.template [deleted file]
etc/open/posting_dupe.template [deleted file]
etc/open/prepare_mail.template [deleted file]
etc/open/preparemail.template [new file with mode: 0755]
etc/open/search_results.template
etc/open/sessionerror.template
etc/open/unsupportedmediatype.template
etc/producer/RSS-full.template [new file with mode: 0755]
etc/producer/RSS.template
etc/producer/article.template
etc/producer/featurearchive.template
etc/producer/languagebar.template [new file with mode: 0755]
etc/producer/navigation.template
etc/producer/newswirearchive.template
etc/producer/producers.xml
etc/producer/radicalendar.template [new file with mode: 0755]
etc/producer/routines.template
etc/producer/startpage.template
etc/producer/topicpage.template
etc/scripts/bundletool.sh [new file with mode: 0755]
etc/scripts/produce.sh [new file with mode: 0755]
etc/scripts/reload.sh [new file with mode: 0755]
etc/server.xml [deleted file]
etc/web.xml [deleted file]
lib/README.txt
lib/commons-dbcp-1.1.jar [new file with mode: 0755]
lib/commons-fileupload-1.0-beta-1.jar [deleted file]
lib/commons-fileupload-1.0.jar [new file with mode: 0755]
lib/commons-httpclient-2.0.jar [new file with mode: 0755]
lib/commons-pool-1.1.jar [new file with mode: 0755]
lib/poolman.jar [deleted file]
lib/postgresql-72jdbc2.jar [deleted file]
lib/postgresql-74jdbc2.jar [new file with mode: 0755]
lib/strutsmesg.jar [deleted file]
lib/xmlrpc-1.2-b1.jar [new file with mode: 0755]
meta/web.xml [new file with mode: 0755]
perms.sh-dist
scripts/produce.sh [deleted file]
scripts/search.pl [deleted file]
source/Mir.java
source/OpenMir.java
source/default.properties
source/mir/bundle/BasicBundleFactory.java [new file with mode: 0755]
source/mir/bundle/Bundle.java [new file with mode: 0755]
source/mir/bundle/BundleFactory.java [new file with mode: 0755]
source/mir/bundle/BundleLoader.java [new file with mode: 0755]
source/mir/bundle/CascadingBundleFactory.java [new file with mode: 0755]
source/mir/bundle/PropertiesBundle.java [new file with mode: 0755]
source/mir/bundle/PropertiesFileBundleLoader.java [new file with mode: 0755]
source/mir/config/MirPropertiesConfiguration.java
source/mir/entity/AbstractEntity.java
source/mir/entity/EntityList.java
source/mir/entity/adapter/EntityListAdapter.java
source/mir/generator/CompositeGeneratorLibrary.java
source/mir/generator/FreemarkerGenerator.java
source/mir/generator/Generator.java
source/mir/generator/GeneratorHelper.java
source/mir/generator/GeneratorLibraryRepository.java
source/mir/generator/TALGenerator.java
source/mir/generator/VelocityGenerator.java
source/mir/generator/tal/CachingFileLoader.java
source/mir/generator/tal/MirExpressionParser.java
source/mir/generator/tal/SimpleTemplateNodeLibraryRegistry.java [new file with mode: 0755]
source/mir/generator/tal/TALTemplateEngine.java
source/mir/generator/tal/TALTemplateParser.java
source/mir/generator/tal/TALTest.java
source/mir/generator/tal/interfaces/TALExpressionParser.java
source/mir/generator/tal/template/CompositeTemplateNode.java
source/mir/generator/tal/template/CoreTemplateNodeLibrary.java [new file with mode: 0755]
source/mir/generator/tal/template/MacroTemplateNodeLibrary.java [new file with mode: 0755]
source/mir/generator/tal/template/PlainTextTemplateNode.java
source/mir/generator/tal/template/TALBasicTemplateNodeLibrary.java [deleted file]
source/mir/generator/tal/template/TALTemplate.java [deleted file]
source/mir/generator/tal/template/TALTemplateNodeLibrary.java [deleted file]
source/mir/generator/tal/template/Template.java [new file with mode: 0755]
source/mir/generator/tal/template/TemplateLibrary.java [new file with mode: 0755]
source/mir/generator/tal/template/TemplateNode.java
source/mir/generator/tal/template/TemplateNodeLibrary.java [new file with mode: 0755]
source/mir/generator/tal/template/TemplateNodeLibraryRegistry.java [new file with mode: 0755]
source/mir/generator/tal/template/TemplateProcessingException.java
source/mir/log/Log.java [deleted file]
source/mir/log/Logger.java
source/mir/log/LoggerEngine.java [new file with mode: 0755]
source/mir/log/LoggerExc.java [new file with mode: 0755]
source/mir/log/LoggerFailure.java [new file with mode: 0755]
source/mir/log/LoggerWrapper.java
source/mir/log/TestFramework.java [deleted file]
source/mir/log/log4j/LoggerImpl.java
source/mir/media/MediaHandler.java
source/mir/misc/FileUtil.java
source/mir/module/AbstractModule.java
source/mir/producer/BundleProducerNode.java [new file with mode: 0755]
source/mir/producer/CompositeProducerNode.java
source/mir/producer/DirCopyingProducerNode.java
source/mir/producer/EntityBatchingProducerNode.java
source/mir/producer/EntityEnumeratingProducerNode.java
source/mir/producer/EntityListProducerNode.java
source/mir/producer/ExecuteProgramProducerNode.java [new file with mode: 0755]
source/mir/producer/ExternalDbProducerNode.java [new file with mode: 0755]
source/mir/producer/FileDateSettingProducerNode.java
source/mir/producer/GeneratingProducerNode.java
source/mir/producer/ProducerFactory.java
source/mir/producer/ProducerNode.java
source/mir/producer/RSSProducerNode.java
source/mir/producer/ResourceBundleProducerNode.java [deleted file]
source/mir/producer/ScriptCallingProducerNode.java [deleted file]
source/mir/producer/reader/DefaultProducerNodeBuilders.java
source/mir/producer/reader/ProducerConfigReader.java
source/mir/producer/reader/ScriptedProducerFactory.java
source/mir/rss/RSS091Reader.java
source/mir/rss/RSSAggregator.java
source/mir/rss/RSSData.java
source/mir/rss/RSSReader.java
source/mir/rss/RSSTest.java [deleted file]
source/mir/servlet/AbstractServlet.java
source/mir/servlet/ServletModule.java
source/mir/session/CommonsUploadedFileAdapter.java
source/mir/session/HTTPAdapters.java
source/mir/session/Request.java
source/mir/session/UploadedFile.java
source/mir/storage/Database.java
source/mir/storage/StorageObject.java
source/mir/storage/store/ObjectStore.java
source/mir/storage/store/StoreUtil.java
source/mir/util/CachingRewindableIterator.java
source/mir/util/ExceptionFunctions.java
source/mir/util/FileFunctions.java
source/mir/util/GeneratorDateTimeFunctions.java
source/mir/util/GeneratorExpressionFunctions.java [deleted file]
source/mir/util/GeneratorFormatAdapters.java
source/mir/util/GeneratorHTMLFunctions.java [deleted file]
source/mir/util/GeneratorIntegerFunctions.java [deleted file]
source/mir/util/GeneratorListFunctions.java [deleted file]
source/mir/util/GeneratorRegularExpressionFunctions.java [deleted file]
source/mir/util/GeneratorStringFunctions.java [deleted file]
source/mir/util/HTTPClientHelper.java [new file with mode: 0755]
source/mir/util/HTTPParsedRequest.java
source/mir/util/HTTPRequestParser.java
source/mir/util/InternetFunctions.java
source/mir/util/ParameterExpander.java
source/mir/util/ReflectionRoutines.java [new file with mode: 0755]
source/mir/util/ResourceBundleGeneratorFunction.java [deleted file]
source/mir/util/StreamCopier.java [new file with mode: 0755]
source/mir/util/StringParseRoutines.java
source/mir/util/StringRoutines.java
source/mir/util/StructuredContentParser.java
source/mir/util/generator/BundleGeneratorFunction.java [new file with mode: 0755]
source/mir/util/generator/ReflectionGeneratorFunctionAdapter.java [new file with mode: 0755]
source/mir/util/generator/ReflectionGeneratorFunctionsAdapter.java [new file with mode: 0755]
source/mir/util/xml/XMLParserEngine.java
source/mir/util/xml/XMLReaderTool.java
source/mir/util/xml/XMLSAXParserProvider.java
source/mir/util/xml/html/HTMLScanner.java
source/mir/util/xml/html/HTMLSchemaInformation.java
source/mircoders/accesscontrol/AccessControl.java
source/mircoders/entity/EntityContent.java
source/mircoders/entity/EntityImages.java
source/mircoders/entity/EntityUploadedMedia.java
source/mircoders/global/Abuse.java
source/mircoders/global/DatabaseEngine.java [new file with mode: 0755]
source/mircoders/global/MRUCache.java
source/mircoders/global/MirGlobal.java
source/mircoders/global/MirGlobalExc.java [new file with mode: 0755]
source/mircoders/global/MirGlobalFailure.java [new file with mode: 0755]
source/mircoders/global/ProducerEngine.java
source/mircoders/localizer/MirAdminInterfaceLocalizer.java
source/mircoders/localizer/MirAntiAbuseFilterType.java
source/mircoders/localizer/MirCachingLocalizerDecorator.java
source/mircoders/localizer/MirGeneratorLocalizer.java
source/mircoders/localizer/MirOpenPostingLocalizer.java
source/mircoders/localizer/MirProducerLocalizer.java
source/mircoders/localizer/basic/MirBasicAdminInterfaceLocalizer.java
source/mircoders/localizer/basic/MirBasicAntiAbuseFilterTypes.java
source/mircoders/localizer/basic/MirBasicArticlePostingHandler.java
source/mircoders/localizer/basic/MirBasicChildArticlePostingHandler.java
source/mircoders/localizer/basic/MirBasicCommentPostingHandler.java
source/mircoders/localizer/basic/MirBasicDataModelLocalizer.java
source/mircoders/localizer/basic/MirBasicEmailArticleHandler.java
source/mircoders/localizer/basic/MirBasicGeneratorLocalizer.java
source/mircoders/localizer/basic/MirBasicOpenPostingLocalizer.java
source/mircoders/localizer/basic/MirBasicPostingSessionHandler.java
source/mircoders/localizer/basic/MirBasicProducerAssistantLocalizer.java
source/mircoders/localizer/basic/MirBasicProducerLocalizer.java
source/mircoders/localizer/basic/MirBasicUtilityFunctions.java [new file with mode: 0755]
source/mircoders/localizer/basic/actions/ArticleTopicAction.java [new file with mode: 0755]
source/mircoders/localizer/basic/filters/ThrottleFilter.java [new file with mode: 0755]
source/mircoders/media/AbstractMediaHandler.java [new file with mode: 0755]
source/mircoders/media/ImageProcessor.java
source/mircoders/media/MediaHandlerAudio.java
source/mircoders/media/MediaHandlerGeneric.java
source/mircoders/media/MediaHandlerImages.java
source/mircoders/media/MediaHandlerImagesExtern.java
source/mircoders/media/MediaHandlerImagesJpeg.java
source/mircoders/media/MediaHandlerMp3.java
source/mircoders/media/MediaHandlerOgg.java
source/mircoders/media/MediaHandlerRealAudio.java
source/mircoders/media/MediaHandlerRealVideo.java
source/mircoders/media/MediaHandlerVideo.java
source/mircoders/media/MediaUploadProcessor.java
source/mircoders/media/URLMediaHandler.java
source/mircoders/media/UnsupportedMediaTypeExc.java [new file with mode: 0755]
source/mircoders/module/ModuleArticleType.java
source/mircoders/module/ModuleBreaking.java
source/mircoders/module/ModuleComment.java
source/mircoders/module/ModuleCommentStatus.java
source/mircoders/module/ModuleContent.java
source/mircoders/module/ModuleImages.java
source/mircoders/module/ModuleLanguage.java
source/mircoders/module/ModuleMediaType.java
source/mircoders/module/ModuleMediafolder.java
source/mircoders/module/ModuleMessage.java
source/mircoders/module/ModuleTopics.java
source/mircoders/module/ModuleUploadedMedia.java
source/mircoders/module/ModuleUsers.java
source/mircoders/pdf/PDFGenerator.java
source/mircoders/producer/ContentModifyingProducerNode.java
source/mircoders/producer/IndexingProducerNode.java
source/mircoders/producer/RadicalendarProducerNode.java [new file with mode: 0755]
source/mircoders/producer/UnIndexingProducerNode.java
source/mircoders/producer/reader/SupplementalProducerNodeBuilders.java
source/mircoders/search/AudioSearchTerm.java
source/mircoders/search/ImagesSearchTerm.java
source/mircoders/search/IndexUtil.java
source/mircoders/search/VideoSearchTerm.java
source/mircoders/servlet/ServletHelper.java
source/mircoders/servlet/ServletModuleAbuse.java
source/mircoders/servlet/ServletModuleAdmin.java
source/mircoders/servlet/ServletModuleArticleType.java
source/mircoders/servlet/ServletModuleAudio.java
source/mircoders/servlet/ServletModuleBreaking.java
source/mircoders/servlet/ServletModuleComment.java
source/mircoders/servlet/ServletModuleCommentStatus.java
source/mircoders/servlet/ServletModuleContent.java
source/mircoders/servlet/ServletModuleFileEdit.java
source/mircoders/servlet/ServletModuleHidden.java
source/mircoders/servlet/ServletModuleImages.java
source/mircoders/servlet/ServletModuleLanguage.java
source/mircoders/servlet/ServletModuleLocalizer.java
source/mircoders/servlet/ServletModuleMediaType.java
source/mircoders/servlet/ServletModuleMediafolder.java
source/mircoders/servlet/ServletModuleMessage.java
source/mircoders/servlet/ServletModuleOpenIndy.java
source/mircoders/servlet/ServletModuleOtherMedia.java
source/mircoders/servlet/ServletModuleProducer.java
source/mircoders/servlet/ServletModuleTopics.java
source/mircoders/servlet/ServletModuleUploadedMedia.java
source/mircoders/servlet/ServletModuleUsers.java
source/mircoders/servlet/ServletModuleVideo.java
source/mircoders/storage/DatabaseArticleType.java
source/mircoders/storage/DatabaseComment.java
source/mircoders/storage/DatabaseCommentToMedia.java
source/mircoders/storage/DatabaseContent.java
source/mircoders/storage/DatabaseContentToMedia.java
source/mircoders/storage/DatabaseContentToTopics.java
templates/admin/FUNCTIONS.template
templates/admin/FUNCTIONS_media.template
templates/admin/comment.template
templates/admin/commentlist.template
templates/admin/content.template
templates/admin/contentlist.template
templates/admin/mediatypelist.template
templates/admin/start_admin.template
templates/admin/superusermenu.template
web/produced/img/arrow_down.gif [deleted file]
web/produced/img/audio_big.gif [deleted file]
web/produced/img/audio_small.gif [deleted file]
web/produced/img/bashcomp2.gif [deleted file]
web/produced/img/cleft.gif [deleted file]
web/produced/img/dot.gif [deleted file]
web/produced/img/extlink.gif [deleted file]
web/produced/img/help.gif [deleted file]
web/produced/img/intlink.gif [deleted file]
web/produced/img/link_small.gif [deleted file]
web/produced/img/logo_small.gif [deleted file]
web/produced/img/mail_small.gif [deleted file]
web/produced/img/maillink.gif [deleted file]
web/produced/img/photo_big.gif [deleted file]
web/produced/img/photo_small.gif [deleted file]
web/produced/img/pointgris.gif [deleted file]
web/produced/img/search_icon.gif [deleted file]
web/produced/img/sp.gif [deleted file]
web/produced/img/text_big.gif [deleted file]
web/produced/img/text_small.gif [deleted file]
web/produced/img/video_big.gif [deleted file]
web/produced/img/video_small.gif [deleted file]
web/produced/style/formate.css [deleted file]
web/produced/style/mir.css [deleted file]

index c130914..d51dd90 100755 (executable)
--- a/build.xml
+++ b/build.xml
-<project name="Mir" default="compile" basedir=".">
+<project name="Mir" default="deploy" basedir=".">
+  <!--
+    - Build script for the Mir project
+    -
+    - usefull tasks are:
+    -   * compile
+    -        Creates the jars needed for a mir deployment
+    -   * deploy
+    -        Sets up a deployment directory
+    -   * binary-distribution
+    -        Sets up a distributable version of mir in the
+    -        form of a war file
+    -   * source-distribution
+    -        Sets up a distributable version of mir as a
+    -        zipped version of the source tree
+    -   * javadoc
+    -        Generates the project's javadoc
+    -->
+
+  <property name="version"        value="1.1.0rc0"/>
 
-<!-- Property Definitions
+  <property name="app.name"       value="mir"/>
 
-     Please not that only the first couple of properties have to be defined.
-     The rest, residing below the "no customization needed" line may be
-     customized if you know what you are doing. Else, leave the defaults
-     and use them to look up where ant places all the files.
+  <!-- -->
+  <property name="deploy.home"    value="./bin/${app.name}"/>
 
-     app.name          Base name of this application, used to
-                       construct filenames and directories.
+  <!-- The distribution will be built here: -->
+  <property name="distribution.home"      value="./dist"/>
 
-     deploy.home       The name of the directory into which the
-                       deployment hierarchy will be created.
-                       Normally, this will be the name of a
-                       subdirectory under $TOMCAT_HOME/webapps.
 
-     deploy.classes    The name of the directory that will contain
-                       the class files.
 
-     dist.home        The name of the base directory in which
-                       distribution files are created.
+  <!-- The temporary files made during the build process
+       will be created here: -->
+  <property name="build"     value="./build"/>
+  <property name="build.classes"  value="./${build}/classes"/>
+  <property name="build.jars"  value="./${build}/jars"/>
+  <property name="build.javadoc"   value="${build}/javadoc"/>
 
-     dist.src          The name of the distribution JAR file
-                       containing the application source code,
-                       to be stored in the "dist.home" directory.
-                       This filename should end with ".jar".
+  <!-- retrieve environment variables -->
+  <property environment="env"/>
 
-     dist.war          The name of the Web ARchive (WAR) file
-                       containing our deployable application.
-                       This filename should end with ".war".
+  <property name="tomcat.home"    value="${env.TOMCAT_HOME}"/>
 
-     javadoc.home      The name of the base directory in which
-                       the JavaDoc documentation for this application
-                       is generated.
+<!--
+  <property name="compile.optimize" value="off" />
+  <property name="compile.debug" value="on" />
+  -->
 
-     tomcat.home       The name of the base directory in which
-                       Tomcat has been installed.  This value is
-                       normally set automatically from the value
-                       of the TOMCAT_HOME environment variable.
+  <target name="deploy" depends="compile,generate-deployment-tree" 
+      description="Sets up a deployment directory">
+  </target>
 
-       java.home          The location of your Java SDK.
+  <target name="debug" depends="compile-debug,generate-deployment-tree"
+      description="Sets up a deployment directory with debug enabled">
+  </target>
 
-       java.localhome     Where your local java classes and jar files
-                       are located.
+  <target name="generate-deployment-tree">
+    <property name="destination" value="${deploy.home}"/>
+    <mkdir  dir="${destination}"/>
+    <mkdir  dir="${destination}/WEB-INF"/>
+    <delete dir="${destination}/WEB-INF/lib"/>
+    <mkdir  dir="${destination}/WEB-INF/lib"/>
+    <mkdir  dir="${destination}/WEB-INF/log"/>
 
-       tomcat.home        The location of the tomcat root directory.
+    <copy todir="${destination}">
+      <fileset dir="web"/>
+    </copy>
 
--->
+    <copy todir="${destination}/WEB-INF/etc">
+      <fileset dir="etc" excludes="extrasource,extralib"/>
+    </copy>
 
-  <property name="app.name"       value="mir"/>
-  <property name="deploy.home"    value="./bin/${app.name}"/>
+    <copy todir="${destination}/WEB-INF">
+      <fileset dir="meta"/>
+    </copy>
 
-  <!-- don't use unless your Jikes is >= v1.18 -->
-  <!-- <property name="build.compiler"   value="jikes"/>-->
+    <copy todir="${destination}/WEB-INF/templates">
+      <fileset dir="templates"/>
+    </copy>
 
+    <copy todir="${destination}/WEB-INF/bundles">
+      <fileset dir="bundles"/>
+    </copy>
 
-<!-- No customization required after this line -->
+    <copy todir="${destination}/WEB-INF" file="source/default.properties" />
 
-  <property environment="env"/>
-  <property file="build.properties"/>
-  <property name="dist.home"      value="${deploy.home}"/>
-  <property name="deploy.webinf"  value="${deploy.home}/WEB-INF"/>
-  <property name="deploy.classes" value="${deploy.webinf}/classes"/>
-  <property name="dist.src"       value="${app.name}.jar"/>
-  <property name="dist.war"       value="${app.name}.war"/>
-  <property name="javadoc.home"   value="${deploy.home}/javadoc"/>
-  <property name="tomcat.home"    value="${env.TOMCAT_HOME}"/>
-  <property name="compile.optimize" value="off" />
-  <property name="compile.debug" value="on" />
+    <copy todir="${destination}/WEB-INF/lib">
+      <fileset dir="lib" />
+      <fileset dir="etc/extralib" />
+      <fileset dir="${build.jars}" />
+    </copy>
+  </target>
 
+  <target name="clean">
+    <delete dir="${build}"/>
+  </target>
 
   <!-- Construct the classpath -->
-  <path id="project.class.path">
-    <pathelement path="${deploy.home}"/>
-    <pathelement path="${deploy.classes}"/>
-    <pathelement path="source"/>
-    <pathelement path="etc/extrasource"/>
+  <path id="project.classpath">
     <fileset dir="lib">
       <include name="*.jar"/>
     </fileset>
+    <fileset dir="etc/extralib">
+      <include name="*.jar"/>
+    </fileset>
 
     <pathelement path="${tomcat.home}/lib/tomcat.jar"/>
-  <!-- for libs shared between tomcat and webapps (tomcat 3.3.x) -->
-       <fileset dir="${tomcat.home}">
-               <include name="lib/common/*.jar" />
-       </fileset>
-  <!-- for libs shared between webapps (tomcat 3.3.x) -->
-       <fileset dir="${tomcat.home}">
-               <include name="lib/apps/*.jar" />
-       </fileset>
-  <!-- for libs shared between tomcat and webapps (tomcat 4.x.x) -->
-       <fileset dir="${tomcat.home}">
-               <include name="common/lib/*.jar" />
-       </fileset>
-  <!-- for libs shared between webapps (tomcat 4.0.x) -->
-       <fileset dir="${tomcat.home}">
-               <include name="lib/*.jar" />
-       </fileset>
-  <!-- for libs shared between webapps (tomcat 4.1.x) -->
-       <fileset dir="${tomcat.home}">
-               <include name="shared/lib/*.jar" />
-       </fileset>
-       <fileset dir="${tomcat.home}">
-               <include name="common/endorsed/*.jar" />
-       </fileset>
-  </path>
-
-  <target name="prepare">
-    <mkdir  dir="${deploy.home}"/>
-    <mkdir  dir="${deploy.webinf}"/>
-    <mkdir  dir="${deploy.classes}"/>
-    <mkdir  dir="${deploy.webinf}/log"/>
 
-    <copy todir="${deploy.home}">
-      <fileset dir="web"/>
-    </copy>
+    <!-- for libs shared between tomcat and webapps (tomcat 3.3.x) -->
+    <fileset dir="${tomcat.home}">
+                 <include name="lib/common/*.jar" />
+         </fileset>
+    <!-- for libs shared between webapps (tomcat 3.3.x) -->
+         <fileset dir="${tomcat.home}">
+                 <include name="lib/apps/*.jar" />
+         </fileset>
+    <!-- for libs shared between tomcat and webapps (tomcat 4.x.x) -->
+         <fileset dir="${tomcat.home}">
+                 <include name="common/lib/*.jar" />
+         </fileset>
+    <!-- for libs shared between webapps (tomcat 4.0.x) -->
+         <fileset dir="${tomcat.home}">
+                 <include name="lib/*.jar" />
+         </fileset>
+    <!-- for libs shared between webapps (tomcat 4.1.x) -->
+         <fileset dir="${tomcat.home}">
+                 <include name="shared/lib/*.jar" />
+         </fileset>
+
+         <fileset dir="${tomcat.home}">
+                 <include name="common/endorsed/*.jar" />
+         </fileset>
+  </path>
 
-    <copy todir="${deploy.webinf}/etc">
-      <fileset dir="etc" excludes="bundles/** web.xml"/>
-    </copy>
-    <copy todir="${deploy.classes}/bundles">
-        <fileset dir="etc/bundles"/>
-    </copy>
-    <copy todir="${deploy.webinf}" file="etc/web.xml"/>
 
-    <copy todir="${deploy.webinf}/templates">
-      <fileset dir="templates"/>
-    </copy>
-    
-    <copy todir="${deploy.webinf}" file="source/default.properties" />
-    
-    <copy todir="${deploy.classes}/bundles">
-      <fileset dir="bundles"/>
-    </copy>
-    
-    <copy todir="${deploy.home}/WEB-INF/lib">
-      <fileset dir="lib" />
-    </copy>
+  <target name="prepare-compilation">
+    <mkdir  dir="${build.classes}"/>
+    <mkdir  dir="${build.jars}"/>
+    <uptodate property="up.to.date" targetfile="${build.jars}/mir.jar">
+      <srcfiles dir="source" includes="**/*.java"/>
+      <srcfiles dir="lib" includes="*.jar"/>
+      <srcfiles dir="etc/extrasource" includes="**/*"/>
+      <srcfiles dir="etc/extralib" includes="*"/>
+    </uptodate>
   </target>
 
-  <target name="clean">
-    <delete dir="${deploy.classes}"/>
-    <mkdir dir="${deploy.classes}"/>
-  </target>
+  <!-- compile target: compiles all files into the build/classes dir -->
+  <target name="compile" depends="prepare-compilation" unless="up.to.date"
+          description="Creates the jars needed for a mir deployment">
+          
+    <javac destdir="${build.classes}" debug="true">
+      <src path="source"/>
+      <src path="etc/extrasource"/>
+      <classpath refid="project.classpath"/>
+    </javac>
 
-  <target name="mrproper">
-    <delete dir="${deploy.home}"/>
+    <jar
+       jarfile="${build.jars}/mir.jar">
+      <fileset dir="${build.classes}" includes="**/*.class" />
+      <manifest>
+        <attribute name="Built-By" value="${user.name}"/>
+      </manifest>
+    </jar>
   </target>
-  
-  <!-- drop out if $TOMCAT_HOME is not set>-->
-  <target name="testtomcat" unless="tomcat.present">
-    <fail message="the $$TOMCAT_HOME environment variable is not set or is set to the wrong path. Please set it first. giving up!"/>
-  </target>
-
-  <target name="compile" depends="prepare">
-    <!-- check to see if $TOMCAT_HOME was set to something useful.. -->
-    <available file="${tomcat.home}/conf" property="tomcat.present"/>
-    <antcall target="testtomcat"/>
-    <dependset>
-      <srcfileset dir="source" includes="**/*.java"/>
-      <srcfileset dir="lib" includes="*.jar"/>         
-      <targetfileset dir="${deploy.classes}" includes="**/*.class"/>
-       <!-- ML: now why can't this be added?
-      <srcfileset dir="etc/extrasource" includes="**/*.java"/> -->   
-    </dependset>
-    <javac destdir="${deploy.classes}"
-           debug="${compile.debug}" optimize="${compile.optimize}" deprecation="on">
+
+  <!-- compile a debuggable version -->
+  <target name="compile-debug" depends="prepare-compilation">
+    <javac destdir="${build.classes}"
+           debug="on" optimize="off" deprecation="on">
       <src path="source"/>
       <src path="etc/extrasource"/>
-      <classpath refid="project.class.path"/>
+      <classpath refid="project.classpath"/>
     </javac>
   </target>
 
-  <target name="javadoc" depends="prepare">
-    <javadoc packagenames="mir.*, mircoders.*"
-            sourcefiles="source/Mir.java,source/OpenMir.java"
-            sourcepath="source"
-             destdir="${javadoc.home}">
-         <classpath refid="project.class.path"/>
-       </javadoc>
+
+  <!-- build the project's javadoc -->
+  <target name="javadoc" depends="prepare-javadoc">
+    <javadoc
+        destdir="${build.javadoc}"
+        author="true"
+        version="true"
+        use="true"
+        packagenames="mir.*,mircoders.*"
+        sourcepath="source"
+        sourcefiles="source/Mir.java,source/OpenMir.java"
+        windowtitle="Mir">
+
+      <classpath refid="project.classpath"/>
+      <link href="http://java.sun.com/j2se/1.3/docs/api"/>
+    </javadoc>
+  </target>
+
+  <target name="prepare-javadoc">
+    <mkdir  dir="${build.javadoc}"/>
   </target>
 
-  <target name="all" depends="clean,prepare,compile,javadoc"/>
+  <target name="prepare-binary-distribution">
+    <mkdir  dir="${distribution.home}"/>
+    <delete dir="${build}/binarydist"/>
+    <mkdir  dir="${build}/binarydist"/>
+  </target>
+
+  <target name="binary-distribution" depends="prepare-binary-distribution">
+    <antcall target="generate-deployment-tree">
+      <param name="destination" value="${build}/binarydist"/>
+    </antcall>
+
+    <zip zipfile="${distribution.home}/binary.zip" >
+      <fileset dir="${build}/binarydist" includes="**/*" />
+    </zip>
+  </target>
+
+  <target name="prepare-source-distribution">
+    <mkdir  dir="${distribution.home}"/>
+  </target>
+
+  <target name="source-distribution" depends="prepare-source-distribution">
+    <zip zipfile="${distribution.home}/source.zip" >
+      <fileset dir="."
+        includes="bundles/**/*,source/**/*,etc/**/*,meta/**/*,web/**/*,templates/**/*,dbscripts/**/*,lib/**/*,doc/**/*,build.xml" />
+    </zip>
+
+  </target>
+  
+<!--  
+  
+  <target name="documentation-pdf" description="generates documentation into html form">
+      <xslt in="${temp}/docs/pdf/${document}.xml"
+            out="${temp}/docs/pdf/${document}.fo"
+            style=""/>
+
+      <java classname="org.apache.fop.apps.Fop" fork="yes">
+          <classpath>
+              <fileset dir="lib">
+                  <include name="*.jar"/>
+              </fileset>
+          </classpath>
+
+          <arg value="-fo"/>
+          <arg file="${temp}/docs/pdf/${document}.fo"/>
+          <arg file="${build}/pdfdocs/${document}.pdf"/>
+      </java>
+  </target>
+-->  
+  <target name="prepare-html">
+    <mkdir dir="${build}/xslt"/>
+    <unzip dest="${build}/xslt">
+      <fileset dir="doc/lib">\r
+          <include name="*.zip"/>\r
+      </fileset>    
+    </unzip>
+    <copy todir="${build}/xslt">
+      <fileset dir="doc/style">
+        <include name="*"/>
+      </fileset>
+    </copy>
+  </target>
+  
+  <target name="documentation-html" description="generates documentation into html form" depends="prepare-html">
+    <mkdir dir="${build}/htmldocs"/>
+
+    <xslt basedir="doc/installation" includes="*.xml"
+          destdir="${build}/htmldocs"
+          style="${build}/xslt/html.xsl"/>
+  </target>
+  
 
 </project>
index a5c7253..6e7f4fa 100755 (executable)
@@ -1,6 +1,6 @@
 ########## admin ##########
 # language: english
-# $Id: admin_en.properties,v 1.48.2.22 2004/01/18 17:30:55 zapata Exp $
+# $Id: admin_en.properties,v 1.48.2.23 2004/11/21 22:07:12 zapata Exp $
 
 languagename=English
 
@@ -25,6 +25,7 @@ delete=delete
 add=add
 filter=filter
 attach=attach
+deattach=remove
 list=browse
 back=back
 cancel=cancel
@@ -147,6 +148,7 @@ commentsearch.field.creator = Author
 commentsearch.field.main_url = Url
 commentsearch.field.email = Email
 commentsearch.field.description = Description
+commentsearch.field.comment = Internal comment
 commentsearch.value = Value
 
 commentsearch.publishedstate = Published state
@@ -232,6 +234,8 @@ content.operation.hide=hide
 content.operation.unhide=unhide
 content.operation.newswire=newswire
 
+content.preview.default = Preview
+
 contentsearch.value = search
 contentsearch.field = field
 contentsearch.field.title = Title
@@ -239,6 +243,7 @@ contentsearch.field.creator = Author
 contentsearch.field.contents=Contents
 contentsearch.field.creator_email = Email
 contentsearch.field.creator_main_url = Web address
+contentsearch.field.comment = Internal comment
 
 contentsearch.publishedstate = publication state
 contentsearch.publishedstate.hidden=hidden
@@ -448,12 +453,16 @@ superusermenu.htmltitle = Super-user functions
 superusermenu.manage = MANAGE
 superusermenu.topics = topics
 superusermenu.articletypes =  article types
-superusermenu.mediatypes = Mediatypes
+superusermenu.mediatypes = mediatypes
 superusermenu.comment_statuses =  comment status values
 superusermenu.users =  users
 superusermenu.languages =  languages
 superusermenu.abuse = apply anti-abuse measures
 superusermenu.imcs =  IMCS (obsolete)
+superusermenu.reload=  reload bundles, logging and producers
+
+infomessage.reloadSuccessfull = reload successfull
+infomessage.reloadFailed= An error has occurred while reloading: <br>{0}
 
 
 #abuse
@@ -497,6 +506,8 @@ abuse.filter.htmltitle = Edit filter
 abuse.filtertype.ip = IP Number
 abuse.filtertype.regexp = Regular expression
 abuse.filtertype.useragent= User Agent
+abuse.filtertype.throttle = Throttle
+abuse.filtertype.hostname = Host name
 
 abuse.filtererror.title = Error:
 abuse.filtererror.invalidtype = Invalid filter type
index 54b446e..c6ed7ea 100755 (executable)
@@ -1,6 +1,6 @@
 ########## admin ##########
 # language: spanish
-# $Id: admin_es.properties,v 1.29.2.3 2004/01/11 20:35:50 zapata Exp $
+# $Id: admin_es.properties,v 1.29.2.4 2004/11/21 22:07:12 zapata Exp $
 
 languagename = Castellano
 
@@ -25,6 +25,8 @@ delete = borrar
 add = a\u00f1adir
 filter = filtrar
 attach = adjuntar
+# missing (master value = "remove")
+deattach = 
 list = mostrar lista
 back = atr\u00e1s
 cancel = cancelar
@@ -45,14 +47,11 @@ no_matches_found = \u00a1No se encontraron coincidencias!
 list.next = siguiente
 list.previous = anterior
 
-# missing (master value = "Status:")
-system.status = 
-# missing (master value = "Logged in:")
-system.loggedin = 
+system.status = Situaci\u00f3n:
+system.loggedin = Identificado:
 
 # media - used by image, audio, video and other media
-# missing (master value = "Urls")
-media.urls = 
+media.urls = URLs
 media.created = creado
 media.changed = \u00faltima modificaci\u00f3n
 media.published = publicado
@@ -73,10 +72,8 @@ media.is_published = Est\u00e1 publicado
 media.icon = Icono
 media.nr_of_media = N\u00famero de recursos medi\u00e1ticos (m\u00e1ximo 20)
 media.nr_of_media.submit = definir n\u00famero
-# missing (master value = "Comments ")
-media.comments = 
-# missing (master value = "Articles")
-media.articles = 
+media.comments = Comentarios
+media.articles = Art\u00edculos
 
 medialist.search_text_in = Buscar texto en
 
@@ -104,8 +101,7 @@ other_medialist.htmltitle = Lista de recursos medi\u00e1ticos
 # breaking
 breaking.htmltitle = \u00daltimas noticias
 breaking.textinfo = (m\u00e1x. 5 l\u00edneas / 250 caracteres)
-# missing (master value = "id")
-breaking.id = 
+breaking.id = Id
 breaking.text = texto
 breaking.date = fecha
 
@@ -127,12 +123,9 @@ comment.article = Art\u00edculo
 comment.html = HTML
 comment.status = Estado
 comment.language = Idioma
-# missing (master value = "All comments")
-comment.allcomments = 
-# missing (master value = "Internal Comment")
-comment.comment = 
-# missing (master value = "(internal)")
-comment.comment.info = 
+comment.allcomments = Todos los comentarios
+comment.comment = Comentario Interno
+comment.comment.info = (interno)
 
 comment.operation.hide = ocultar
 comment.operation.unhide = desocultar
@@ -153,11 +146,11 @@ commentlist.order.articletitle = t\u00edtulo del art\u00edculo
 commentsearch.field = Buscar
 commentsearch.field.title = T\u00edtulo
 commentsearch.field.creator = Autor
-# missing (master value = "Url")
-commentsearch.field.main_url = 
-# missing (master value = "Email")
-commentsearch.field.email = 
+commentsearch.field.main_url = URL
+commentsearch.field.email = Correo-e
 commentsearch.field.description = Descripci\u00f3n
+# missing (master value = "Internal comment")
+commentsearch.field.comment = 
 commentsearch.value = Valor
 
 commentsearch.publishedstate = Estado de publicaci\u00f3n
@@ -200,16 +193,11 @@ content.content = Contenido
 content.html = HTML?
 content.comment = Comentario interno
 content.internal = (prop\u00f3sito interno)
-# missing (master value = "Keywords")
-content.keywords = 
-# missing (master value = "Locked by {0}")
-content.lockedby = 
-# missing (master value = "Lock")
-content.lock = 
-# missing (master value = "Unlock")
-content.unlock = 
-# missing (master value = "Force lock")
-content.forcelock = 
+content.keywords = Palabras clave
+content.lockedby = Bloqueado por {0}
+content.lock = Bloquear
+content.unlock = Desbloquear
+content.forcelock = Forzar bloqueo
 
 content.attachments = Adjuntos
 content.images = Im\u00e1genes
@@ -253,10 +241,10 @@ contentsearch.field = campo
 contentsearch.field.title = T\u00edtulo
 contentsearch.field.creator = Autor
 contentsearch.field.contents = Contenido
-# missing (master value = "Email")
-contentsearch.field.creator_email = 
-# missing (master value = "Web address")
-contentsearch.field.creator_main_url = 
+contentsearch.field.creator_email = Correo-e
+contentsearch.field.creator_main_url = Direcci\u00f3n web
+# missing (master value = "Internal comment")
+contentsearch.field.comment = 
 
 contentsearch.publishedstate = estado de publicaci\u00f3n
 contentsearch.publishedstate.hidden = oculto
@@ -280,8 +268,7 @@ contentlist.select = Seleccionar
 
 # language
 language.htmltitle = Idioma
-# missing (master value = "Id")
-language.id = 
+language.id = Id
 language.name = Idioma
 language.code = C\u00f3digo de idioma
 
@@ -299,8 +286,7 @@ login.submit = Aceptar
 
 # mediafolder
 mediafolder.htmltitle = Carpeta de recursos medi\u00e1ticos
-# missing (master value = "id")
-mediafolder.id = 
+mediafolder.id = id
 mediafolder.date = fecha
 mediafolder.name = nombre
 mediafolder.location = lugar de origen
@@ -312,8 +298,7 @@ mediafolderlist.htmltitle = Lista de carpetas de recursos medi\u00e1ticos
 
 # message
 message.htmltitle = Mensajes
-# missing (master value = "id")
-message.id = 
+message.id = id
 message.date = fecha
 message.title = t\u00edtulo
 message.creator = autor
@@ -327,10 +312,8 @@ start.htmltitle = Administraci\u00f3n
 
 start.content.new = nuevo art\u00edculo
 start.show = mostrar
-# missing (master value = "open comment #")
-start.comment.open_by_id = 
-# missing (master value = "open article #")
-start.content.open_by_id = 
+start.comment.open_by_id = comentario abierto n\u00ba
+start.content.open_by_id = art\u00edculo abierto n\u00ba
 
 start.content.hidden = art\u00edculos ocultos
 start.content.not_published = art\u00edculos (aun) sin publicar
@@ -341,13 +324,11 @@ start.content.all = Todos los art\u00edculos
 start.content.search = buscar
 
 start.allarticlesoftype = {0}
-# missing (master value = "{0}")
-start.allcommentswithstatus = 
+start.allcommentswithstatus = {0}
 
 start.producers.title = GENERAR MANUALMENTE
 start.producers.produceAllNew = generar todos los nuevos
-# missing (master value = "generate all new")
-start.producers.recipe.allnew = 
+start.producers.recipe.allnew = generar todos los nuevos
 
 start.producers.advanced = p\u00e1gina avanzada (usar con cuidado!)
 
@@ -357,22 +338,20 @@ start.administer.comments = comentarios
 start.comments.title = COMENTARIOS
 
 start.breaking.title = \u00faltimas noticias
-# missing (master value = "ARTICLES")
-start.articles.title = 
+start.articles.title = ART\u00cdCULOS
 start.fileedit.includes.title = editar ficheros
 start.addandedit.title = A\u00d1ADIR / EDITAR
 start.extra.title = EXTRA
 start.search.title = BUSCAR
 start.other_media.title = otros recursos medi\u00e1ticos
 start.images.title = im\u00e1genes
-# missing (master value = "open image #")
-start.images.open_by_id = 
+start.images.open_by_id = imagen abierta n\u00ba
 start.video.title = video
 start.audio.title = audio
 start.media.title = MEDIA
 start.mediafolder.title = carpeta de recursos medi\u00e1ticos
 start.languages.title = IDIOMAS
-start.imcs.title = IMCS
+start.imcs.title = IMCs
 start.messageboard.title = TABL\u00d3N DE AVISOS
 start.messageboard.no_messages = no hay mensajes
 
@@ -383,8 +362,7 @@ start.superusermenu = funciones de super-usuario (usar con cuidado!)
 
 topic.htmltitle = tema
 
-# missing (master value = "id")
-topic.id = 
+topic.id = id
 topic.title = nombre
 topic.description = descripci\u00f3n
 topic.filename = nombre del fichero
@@ -397,25 +375,17 @@ topiclist.htmltitle = Lista de temas
 # users
 user.htmltitle = Usuario
 user.login = Usuario
-# missing (master value = "Your own password")
-user.ownpassword = 
-# missing (master value = "Old password")
-user.oldpassword = 
+user.ownpassword = Tu propia contrase\u00f1a
+user.oldpassword = Contrase\u00f1a antigua
 user.password = Contrase\u00f1a
 user.password2 = Contrase\u00f1a (confirmaci\u00f3n)
 user.admin = Administrador
-# missing (master value = "Disabled ?")
-user.is_disabled = 
-# missing (master value = "Creation date")
-user.creationdate = 
-# missing (master value = "Last login")
-user.lastlogindate = 
-# missing (master value = "Email address")
-user.email = 
-# missing (master value = "Comment")
-user.comment = 
-# missing (master value = "Profile")
-user.profile = 
+user.is_disabled = Desabilitar?
+user.creationdate = Fecha creaci\u00f3n
+user.lastlogindate = \u00daltimo login
+user.email = Direcci\u00f3n correo-e
+user.comment = Comentario
+user.profile = Perfil
 
 
 
@@ -425,23 +395,23 @@ userlist.htmltitle = Lista de usuarios
 
 #articletype
 articletype.htmltitle = Tipo de art\u00edculo
-articletype.id = ID
+articletype.id = Id
 articletype.name = Nombre
 
 articletypelist.htmltitle = Lista de tipos de art\u00edculo
 
 # mediatypes
-mediatypelist.htmltitle = Manage Mediatypes
-mediatype.id = id
-mediatype.name = Name
-mediatype.htmltitle = Mediatype
-mediatype.mimetype = MIME-Type
-mediatype.classname = Classname
-mediatype.tablename = Tabelname
+mediatypelist.htmltitle = Gestionar los Tipos de medios
+mediatype.id = Id
+mediatype.name = Nombre
+mediatype.htmltitle = Tipo de medio
+mediatype.mimetype = Tipo MIME
+mediatype.classname = Nombre de clase
+mediatype.tablename = Nombre de tabla
 
 #commentstatus
 commentstatus.htmltitle = Estado de comentario
-commentstatus.id = ID
+commentstatus.id = Id
 commentstatus.name = Nombre
 
 commentstatuslist.htmltitle = Lista de estados de comentario
@@ -468,13 +438,10 @@ producer.job.name = Trabajo
 producer.job.status = Estado
 producer.job.date = \u00daltima modificacion
 producer.job.empty = La cola est\u00e1 vac\u00eda
-# missing (master value = "Running time")
-producer.job.runningtime = 
+producer.job.runningtime = Tiempo ejecut\u00e1ndose
 
-# missing (master value = "Cancel selected jobs")
-producer.jobqueue.canceljobs = 
-# missing (master value = "Cancel all pending jobs")
-producer.jobqueue.cancelalljobs = 
+producer.jobqueue.canceljobs = Cancelar trabajos seleccionados
+producer.jobqueue.cancelalljobs = Cancelar todos los trabajos pendientes
 producer.jobqueue.title = Trabajos actuales
 producer.jobqueue.refresh = refrescar
 producer.producerlist.title = A\u00f1adir un nuevo trabajo
@@ -487,12 +454,19 @@ superusermenu.htmltitle = Funciones de super-usuario
 superusermenu.manage = GESTIONAR
 superusermenu.topics = temas
 superusermenu.articletypes = tipos de art\u00edculo
-superusermenu.mediatypes = Mediatypes
+superusermenu.mediatypes = Tipos de medios
 superusermenu.comment_statuses = valores de estados de comentario
 superusermenu.users = usuarios
 superusermenu.languages = idiomas
 superusermenu.abuse = aplicar medidas antiabuso
 superusermenu.imcs = IMCs (obsoleto)
+# missing (master value = "reload bundles, logging and producers")
+superusermenu.reload = 
+
+# missing (master value = "reload successfull")
+infomessage.reloadSuccessfull = 
+# missing (master value = "An error has occurred while reloading: <br>{0}")
+infomessage.reloadFailed = 
 
 
 #abuse
@@ -516,52 +490,44 @@ abuse.log.time = Hora
 abuse.log.address = N\u00famero de IP
 abuse.log.object = Objeto
 abuse.log.browser = Navegador
-# missing (master value = "Filter type")
-abuse.log.filtertype = 
-# missing (master value = "Expression")
-abuse.log.filterexpression = 
+abuse.log.filtertype = Tipo de filtro
+abuse.log.filterexpression = Expresi\u00f3n
 
 abuse.filters = Filtros
-# missing (master value = "down")
-abuse.filters.movedown = 
-# missing (master value = "up")
-abuse.filters.moveup = 
+abuse.filters.movedown = abajo
+abuse.filters.moveup = arriba
+# missing (master value = "bottom")
+abuse.filters.movebottom = 
+# missing (master value = "top")
+abuse.filters.movetop = 
 
 abuse.filter.type = Tipos
 abuse.filter.expression = Expresi\u00f3n
-# missing (master value = "Article ")
-abuse.filter.articleaction = 
-# missing (master value = "Comment ")
-abuse.filter.commentaction = 
-# missing (master value = "Comments (internal usage)")
-abuse.filter.comments = 
-# missing (master value = "Last hit")
-abuse.filter.lasthit = 
-# missing (master value = "Edit filter")
-abuse.filter.htmltitle = 
+abuse.filter.articleaction = Art\u00edculo
+abuse.filter.commentaction = Comentario
+abuse.filter.comments = Comentarios (uso interno)
+abuse.filter.lasthit = \u00daltimo hit
+abuse.filter.htmltitle = Editar filtro
 
 abuse.filtertype.ip = N\u00famero de IP
 abuse.filtertype.regexp = Expresi\u00f3n regular
-# missing (master value = "User Agent")
-abuse.filtertype.useragent = 
+abuse.filtertype.useragent = Navegador
+# missing (master value = "Throttle")
+abuse.filtertype.throttle = 
+# missing (master value = "Host name")
+abuse.filtertype.hostname = 
 
-# missing (master value = "Error:")
-abuse.filtererror.title = 
-# missing (master value = "Invalid filter type")
-abuse.filtererror.invalidtype = 
-# missing (master value = "Invalid expression for this type")
-abuse.filtererror.invalidexpression = 
+abuse.filtererror.title = Error:
+abuse.filtererror.invalidtype = Tipo de filtro inv\u00e1lido
+abuse.filtererror.invalidexpression = Expresi\u00f3n inv\u00e1lida para este tipo
 
-# missing (master value = "Anti-abuse filter rules")
-abuse.filters.htmltitle = 
-# missing (master value = "Anti-abuse open posting log")
-abuse.log.htmltitle = 
+abuse.filters.htmltitle = Reglas de filtro antiabuso
+abuse.log.htmltitle = Log de env\u00edos abiertos antiabuso
 
 # head
 head.start = inicio
 head.logout = salir
-# missing (master value = "password")
-head.changepassword = 
+head.changepassword = contrase\u00f1a
 head.help = ayuda
 head.search = buscar
 head.logged_in = identificado
@@ -603,13 +569,11 @@ media.error.unsupportedformat = El formato del recurso medi\u00e1tico que has su
 user.error.missingpasswords = La nueva contrase\u00f1a debe ser introducida dos veces
 user.error.passwordmismatch = Las contrase\u00f1as no son iguales
 user.error.missingpassword = Es necesario introducir alguna contrase\u00f1a
-# missing (master value = "Incorrect password")
-user.error.incorrectpassword = 
+user.error.incorrectpassword = Contrase\u00f1a incorrecta
 
 
 
 
 ########## infomessages ##########
 infomessage.htmltitle = Informaci\u00f3n
-# missing (master value = "Your request has been added to the queue.")
-infomessage.recipeAddedToQueue = 
+infomessage.recipeAddedToQueue = Tu petici\u00f3n ha sido a\u00f1adida a la cola.
index 40a1253..14df868 100755 (executable)
-########## admin ##########
-# language: euskera / basque
-# $Id: admin_eu.properties,v 1.12.2.3 2004/01/11 20:35:50 zapata Exp $
-
-languagename = Euskera
-
-# general
-yes = bai
-no = ez
-dontcare = ez du axola
-all = dena
-# missing (master value = "month")
-month = 
-# missing (master value = "year")
-year = 
-# missing (master value = "file")
-file = 
-# missing (master value = "new")
-new = 
-# missing (master value = "by")
-by = 
-# missing (master value = "help")
-help = 
-
-
-# actions
-insert = sartu
-save = gorde
-edit = aldatu
-delete = ezabatu
-add = gehitu
-filter = iragazi
-attach = atxeki
-list = zerrenda erakutsi
-back = atzera
-cancel = utzi
-preview = aurrebista
-reset = berrasieratu
-# missing (master value = "administer")
-administer = 
-# missing (master value = "search")
-search = 
-
-
-# special
-# missing (master value = "fileEdit")
-fileedit = 
-
-
-# records
-records = sarrerak
-show_from_to = {0}(e)tik {1}(e)ra bitarteko sarrerak erakusten
-no_matches_found = Ez da horrelako sarrerarik aurkitu!
-list.next = hurrengoa
-list.previous = aurrekoa
-
-# missing (master value = "Status:")
-system.status = 
-# missing (master value = "Logged in:")
-system.loggedin = 
-
-# media - used by image, audio, video and other media
-# missing (master value = "Urls")
-media.urls = 
-media.created = sortua
-media.changed = aldatua
-media.published = argitaratua
-media.format = Formatua
-media.rights = Egile eskubideak
-media.type = Mota
-media.mediafolder = Baliabide mediatikoen karpeta
-media.title = Izenburua
-media.size = Tamaina
-media.description = Deskripzioa
-media.date = Data
-media.location = Jatorrizko lekua
-media.creator = Egilea
-media.keywords = Hitz gakoak
-media.comment = Komentarioa
-media.source = Jatorria
-media.is_published = Argitaratzeko prest
-media.icon = Ikonoa
-media.nr_of_media = Baliabide mediatikoen kopurua
-media.nr_of_media.submit = Aldatu kopurua
-# missing (master value = "Comments ")
-media.comments = 
-# missing (master value = "Articles")
-media.articles = 
-
-medialist.search_text_in = Testua non bilatu
-
-
-# image
-image.htmltitle = Irudia
-imagelist.htmltitle = Irudien zerrenda
-
-
-# audio
-audio.htmltitle = Audioa
-audiolist.htmltitle = Audio zerrenda
-
-
-# video
-video.htmltitle = Bideoa
-videolist.htmltitle = Bideo zerrenda
-
-
-# other
-other_media.htmltitle = Baliabide mediatikoen zerrenda
-# missing (master value = "Other media overview")
-other_medialist.htmltitle = 
-
-
-# breaking
-breaking.htmltitle = Azken albisteak
-breaking.textinfo = (gehienez 5 lerrro / 250 letra)
-# missing (master value = "id")
-breaking.id = 
-breaking.text = testua
-breaking.date = data
-
-breakinglist.htmltitle = Azken albisteen zerrenda
-
-
-# comment
-comment.htmltitle = Komentarioa
-comment.date = data
-comment.title = izenburua
-comment.published = argitaratuta
-comment.text = komentarioaren testua
-comment.address = helbidea
-comment.phone = telefonoa
-comment.email = posta elektronikoa
-comment.url = URL
-comment.creator = egilea
-comment.article = Artikuluarena
-comment.html = HTML da?
-comment.status = Egoera
-comment.language = Hizkuntza
-# missing (master value = "All comments")
-comment.allcomments = 
-# missing (master value = "Internal Comment")
-comment.comment = 
-# missing (master value = "(internal)")
-comment.comment.info = 
-
-# missing (master value = "hide")
-comment.operation.hide = 
-# missing (master value = "unhide")
-comment.operation.unhide = 
-
-
-#commentlist
-commentlist.htmltitle = Komentarioen zerrenda
-# missing (master value = "published")
-commentlist.published = 
-commentlist.hidden = izkutua
-# missing (master value = "All comments for this article")
-commentlist.allcomments = 
-commentlist.search = bilatu!
-# missing (master value = "activate changes")
-commentlist.activate = 
-# missing (master value = "order")
-commentlist.order = 
-# missing (master value = "newest first")
-commentlist.order.datedesc = 
-# missing (master value = "oldest first")
-commentlist.order.dateasc = 
-# missing (master value = "article title")
-commentlist.order.articletitle = 
-
-# missing (master value = "Search")
-commentsearch.field = 
-# missing (master value = "Title")
-commentsearch.field.title = 
-# missing (master value = "Author")
-commentsearch.field.creator = 
-# missing (master value = "Url")
-commentsearch.field.main_url = 
-# missing (master value = "Email")
-commentsearch.field.email = 
-# missing (master value = "Description")
-commentsearch.field.description = 
-# missing (master value = "Value")
-commentsearch.value = 
-
-# missing (master value = "Published state")
-commentsearch.publishedstate = 
-# missing (master value = "Hidden")
-commentsearch.publishedstate.hidden = 
-# missing (master value = "Published")
-commentsearch.publishedstate.published = 
-
-# missing (master value = "Status")
-commentsearch.status = 
-
-# missing (master value = "Order")
-commentsearch.order = 
-commentsearch.order.datedesc = data (behera)
-commentsearch.order.dateasc = data (gora)
-commentsearch.order.articletitle = artikuluaren titulua
-
-# missing (master value = "Search")
-commentsearch.searchbutton = 
-
-
-# confirm
-confirm.htmltitle = Ezabaketa baieztatu
-confirm.really_delete = Sarrera hau ezabatu nahi duzu?
-# missing (master value = "This will erase the entry from the database unrecoverably.")
-confirm.text = 
-
-
-# content
-content.htmltitle = Edukia
-content.owner = Jabea
-# missing (master value = "Language")
-content.language = 
-# missing (master value = "Article type")
-content.articletype = 
-content.topic = Gaia
-content.title = Izenburu luzea
-content.subtitle = Azpi-izenburua
-content.edittitle = Testuinguru izenburua
-content.location = Jatorrizko lekua
-content.creator = Egilea
-content.creator.email = Posta elektronikoa
-content.creator.url = Web
-content.creator.address = Helbidea
-content.creator.telephone = Telefonoa
-content.abstract = Deskripzio laburra
-content.content = Edukia
-content.html = HTML da?
-content.comment = Barne komentarioa
-content.internal = (barne xederako)
-# missing (master value = "Keywords")
-content.keywords = 
-# missing (master value = "Locked by {0}")
-content.lockedby = 
-# missing (master value = "Lock")
-content.lock = 
-# missing (master value = "Unlock")
-content.unlock = 
-# missing (master value = "Force lock")
-content.forcelock = 
-
-content.attachments = Atxekiak
-content.images = Irudiak
-content.audio = Audioa
-content.video = Bideoa
-content.other = Beste baliabide mediatikoak
-content.media = Baliabide mediatikoak
-content.addimage = irudia gehitu
-# missing (master value = "upload image")
-content.uploadimage = 
-content.addaudio = audio gehitu
-# missing (master value = "upload audio")
-content.uploadaudio = 
-content.addvideo = bideoa gehitu
-# missing (master value = "upload video")
-content.uploadvideo = 
-content.addother = beste baliabide mediatikoa gehitu
-# missing (master value = "upload other media")
-content.uploadother = 
-
-content.creationdate = data
-content.modificationdate = azken aldaketa
-content.status = Egoera
-content.type = Artikulu mota
-content.import_date = sarreraren data
-content.lastchange_date = azken aldaketa
-content.create_date = data
-content.published = argitaratua
-content.comments = Komentarioak
-
-# missing (master value = "Children & Parents")
-content.family = 
-# missing (master value = "Children")
-content.children = 
-# missing (master value = "view")
-content.viewchildren = 
-# missing (master value = "Parent")
-content.parent = 
-# missing (master value = "view")
-content.viewparent = 
-# missing (master value = "de-select")
-content.clearparent = 
-# missing (master value = "select")
-content.selectparent = 
-
-# missing (master value = "hide")
-content.operation.hide = 
-# missing (master value = "unhide")
-content.operation.unhide = 
-# missing (master value = "newswire")
-content.operation.newswire = 
-
-# missing (master value = "search")
-contentsearch.value = 
-# missing (master value = "field")
-contentsearch.field = 
-# missing (master value = "Title")
-contentsearch.field.title = 
-# missing (master value = "Author")
-contentsearch.field.creator = 
-# missing (master value = "Contents")
-contentsearch.field.contents = 
-# missing (master value = "Email")
-contentsearch.field.creator_email = 
-# missing (master value = "Web address")
-contentsearch.field.creator_main_url = 
-
-# missing (master value = "publication state")
-contentsearch.publishedstate = 
-# missing (master value = "hidden")
-contentsearch.publishedstate.hidden = 
-# missing (master value = "published")
-contentsearch.publishedstate.published = 
-
-# missing (master value = "article type")
-contentsearch.articletype = 
-
-# missing (master value = "order by")
-contentsearch.order = 
-# missing (master value = "Newest first")
-contentsearch.order.datedesc = 
-# missing (master value = "Oldest first")
-contentsearch.order.dateasc = 
-# missing (master value = "Title")
-contentsearch.order.title = 
-# missing (master value = "Author")
-contentsearch.order.creator = 
-# missing (master value = "Search")
-contentsearch.searchbutton = 
-
-
-#contentlist
-contentlist.htmltitle = Edukien zerrenda
-contentlist.comments = komentarioak
-# missing (master value = "Select")
-contentlist.select = 
-
-
-# language
-language.htmltitle = Hizkuntza
-# missing (master value = "Id")
-language.id = 
-language.name = hizkuntza
-language.code = Hizkuntza kodea
-
-languagelist.htmltitle = Hizkuntzen zerrenda
-
-# login
-login.htmltitle = Sarrera
-login.info = Eremu hau baimendutako taldeentzat bakarrik da. Editore lanetan lagundu nahi baduzu, jar zaitez gurekin kontaktuan <a href="mailto:imc-euskalherria-editorial@lists.indymedia.org">imceuskalherria-editorial@lists.indymedia.org</a> helbidean mesedez.
-login.title = erabiltzailea
-login.name = Erabiltzailea
-login.password = Pasahitza
-login.language = Hizkuntza
-login.submit = Ados
-
-
-# mediafolder
-mediafolder.htmltitle = Baliabide mediatikoen karpeta
-# missing (master value = "id")
-mediafolder.id = 
-mediafolder.date = data
-mediafolder.name = izena
-mediafolder.location = jatorrizko lekua
-mediafolder.keywords = hitz gakoak
-mediafolder.comment = komentarioa
-
-mediafolderlist.htmltitle = Baliabide mediatikoen karpeten zerrenda
-
-
-# message
-message.htmltitle = Mezuak
-# missing (master value = "id")
-message.id = 
-message.date = data
-message.title = izenburua
-message.creator = Egilea
-message.text = testua
-message.textinfo = (gehienez 5 lerrro / 250 letra)
-
-messagelist.htmltitle = Mezuen zerrenda
-
-# admin start page
-start.htmltitle = Administrazioa
-
-start.content.new = artikulu berriak
-start.show = Erakutsi
-# missing (master value = "open comment #")
-start.comment.open_by_id = 
-# missing (master value = "open article #")
-start.content.open_by_id = 
-
-start.content.hidden = aritukulu ezkutukoak
-start.content.not_published = argitaratzeke dauden artikuluak
-start.content.with_media = baliabide mediatikoekin
-start.content.last_changes = azken aldaketak
-start.content.with_comments = barne xederako komentarioekin
-start.content.all = Artikulu guztiak
-start.content.search = bilatu
-
-start.allarticlesoftype = {0} motatako artikulu guztiak
-# missing (master value = "{0}")
-start.allcommentswithstatus = 
-
-start.producers.title = Euskuz ekoiztu
-start.producers.produceAllNew = Dena berria ekoiztu
-# missing (master value = "generate all new")
-start.producers.recipe.allnew = 
-
-start.producers.advanced = Aukera arreratuak (kontuz honekin!)
-
-# missing (master value = "ADMINISTER")
-start.administer.title = 
-# missing (master value = "comments")
-start.administer.comments = 
-
-start.comments.title = KOMENTARIOAK
-
-start.breaking.title = AZKEN ALBISTRAK
-# missing (master value = "ARTICLES")
-start.articles.title = 
-# missing (master value = "edit include files")
-start.fileedit.includes.title = 
-# missing (master value = "ADD / EDIT")
-start.addandedit.title = 
-# missing (master value = "EXTRA")
-start.extra.title = 
-# missing (master value = "SEARCH")
-start.search.title = 
-start.other_media.title = BESTE MEDIOEN FITXATEGIAK
-start.images.title = IRUDIAK
-# missing (master value = "open image #")
-start.images.open_by_id = 
-start.video.title = BIDEO FITXATEGIAK
-start.audio.title = AUDIO FITXATEGIAK
-# missing (master value = "MEDIA")
-start.media.title = 
-start.mediafolder.title = BALIABIDE MEDIATIKOEN ZERRENDA
-start.languages.title = IZENBURUA
-start.imcs.title = MIGak
-start.messageboard.title = Barneko mezuak
-start.messageboard.no_messages = ez dago mezurik
-
-start.superusermenu = Aukera aurreratuak (kontuz honekin!)
-
-
-# topic
-
-topic.htmltitle = Gaia
-
-# missing (master value = "id")
-topic.id = 
-topic.title = Izena
-topic.description = deskripzioa
-topic.filename = Fitxategiaren izena
-topic.main_url = Informazio nagusiko orria
-topic.archive_url = Fitxategiaren URLa
-
-topiclist.htmltitle = Gaien zerrenda
-
-
-# users
-user.htmltitle = Erabiltzailea
-user.login = erabiltzailea
-# missing (master value = "Your own password")
-user.ownpassword = 
-# missing (master value = "Old password")
-user.oldpassword = 
-user.password = pasahitza
-# missing (master value = "Password (confirmation)")
-user.password2 = 
-user.admin = administratzailea
-# missing (master value = "Disabled ?")
-user.is_disabled = 
-# missing (master value = "Creation date")
-user.creationdate = 
-# missing (master value = "Last login")
-user.lastlogindate = 
-# missing (master value = "Email address")
-user.email = 
-# missing (master value = "Comment")
-user.comment = 
-# missing (master value = "Profile")
-user.profile = 
-
-
-
-
-userlist.htmltitle = Erabiltzaileen zerrenda
-
-
-#articletype
-articletype.htmltitle = Artikuluen motak
-articletype.id = ID
-articletype.name = Izena
-
-articletypelist.htmltitle = Artikuluen mota zerrenda
-
-# mediatypes
-mediatypelist.htmltitle = Manage Mediatypes
-mediatype.id = id
-mediatype.name = Name
-mediatype.htmltitle = Mediatype
-mediatype.mimetype = MIME-Type
-mediatype.classname = Classname
-mediatype.tablename = Tabelname
-
-#commentstatus
-commentstatus.htmltitle = Komentarioen egoera
-commentstatus.id = ID
-commentstatus.name = Izena
-
-commentstatuslist.htmltitle = Komentarioen egoeraren zerrenda
-
-
-
-#file editing
-fileedit.htmltitle = Fitxategia aldatu
-fileedit.filename = Fitxategiaren izena
-# missing (master value = "Subdirectory")
-fileedit.subdirectory = 
-
-fileeditlist.htmltitle = Fitxategien aldaketak
-fileeditlist.filename = Fitxategiaren izena
-# missing (master value = "Subdirectory")
-fileeditlist.dirname = 
-
-
-#producers
-producer.producer = Ekoizlearen izena
-producer.verb.name = Lanaren izena
-producer.verb.description = Lanaren deskribapena
-producer.verb.enqueue = Eskatu
-
-producer.job.name = Lana
-producer.job.status = Egoera
-producer.job.date = azken aldaketa
-# missing (master value = "Queue is empty")
-producer.job.empty = 
-# missing (master value = "Running time")
-producer.job.runningtime = 
-
-# missing (master value = "Cancel selected jobs")
-producer.jobqueue.canceljobs = 
-# missing (master value = "Cancel all pending jobs")
-producer.jobqueue.cancelalljobs = 
-producer.jobqueue.title = Oraingo lanak
-producer.jobqueue.refresh = birkargatu
-producer.producerlist.title = Lan berri bat gehitu
-
-producerqueue.htmltitle = Eskuz ekoiztu
-
-
-#superusermenu
-superusermenu.htmltitle = Aukera aurreratuak
-# missing (master value = "MANAGE")
-superusermenu.manage = 
-superusermenu.topics = Gaien kudeaketa
-superusermenu.articletypes = Artiukuluen moten kudeaketa
-superusermenu.mediatypes = Mediatypes
-superusermenu.comment_statuses = Komentarioen egoeraren kudeaketa
-superusermenu.users = Erabiltzailen kudeaketa
-superusermenu.languages = Hizkuntzen kudeaketa
-# missing (master value = "apply anti-abuse measures")
-superusermenu.abuse = 
-superusermenu.imcs = MIGen zerrendaren kudeaketa (zaharkitua)
-
-
-#abuse
-# missing (master value = "anti-abuse measures")
-abuse.htmltitle = 
-
-# missing (master value = "Setting")
-abuse.setting = 
-# missing (master value = "Value")
-abuse.value = 
-
-# missing (master value = "Turn off open posting")
-abuse.disableopenpostings = 
-# missing (master value = "Require a password for open postings")
-abuse.openpostingpassword = 
-# missing (master value = "Log IPs for open postings")
-abuse.logpostings = 
-# missing (master value = "Logging buffer size")
-abuse.logsize = 
-# missing (master value = "Use cookies for blocked users")
-abuse.cookies = 
-# missing (master value = "Action for blocked article")
-abuse.articleaction = 
-# missing (master value = "Action for blocked comment")
-abuse.commentaction = 
-
-# missing (master value = "Show the IP log")
-abuse.showlog = 
-# missing (master value = "Manage filters")
-abuse.showfilters = 
-
-# missing (master value = "Time")
-abuse.log.time = 
-# missing (master value = "IP number")
-abuse.log.address = 
-# missing (master value = "Object")
-abuse.log.object = 
-# missing (master value = "Browser")
-abuse.log.browser = 
-# missing (master value = "Filter type")
-abuse.log.filtertype = 
-# missing (master value = "Expression")
-abuse.log.filterexpression = 
-
-# missing (master value = "Filters")
-abuse.filters = 
-# missing (master value = "down")
-abuse.filters.movedown = 
-# missing (master value = "up")
-abuse.filters.moveup = 
-
-# missing (master value = "Type")
-abuse.filter.type = 
-# missing (master value = "Expression")
-abuse.filter.expression = 
-# missing (master value = "Article ")
-abuse.filter.articleaction = 
-# missing (master value = "Comment ")
-abuse.filter.commentaction = 
-# missing (master value = "Comments (internal usage)")
-abuse.filter.comments = 
-# missing (master value = "Last hit")
-abuse.filter.lasthit = 
-# missing (master value = "Edit filter")
-abuse.filter.htmltitle = 
-
-# missing (master value = "IP Number")
-abuse.filtertype.ip = 
-# missing (master value = "Regular expression")
-abuse.filtertype.regexp = 
-# missing (master value = "User Agent")
-abuse.filtertype.useragent = 
-
-# missing (master value = "Error:")
-abuse.filtererror.title = 
-# missing (master value = "Invalid filter type")
-abuse.filtererror.invalidtype = 
-# missing (master value = "Invalid expression for this type")
-abuse.filtererror.invalidexpression = 
-
-# missing (master value = "Anti-abuse filter rules")
-abuse.filters.htmltitle = 
-# missing (master value = "Anti-abuse open posting log")
-abuse.log.htmltitle = 
-
-# head
-head.start = hasiera
-head.logout = irten
-# missing (master value = "password")
-head.changepassword = 
-head.help = laguntza
-head.search = bilatu
-head.logged_in = erregistraturik zaude
-
-# foot
-foot.top = gora
-
-
-########## dynamic values ##########
-
-# (users can add new types, how to translate these)
-# suggestion if not in bundle use value as Text
-
-
-# Article types
-articletypes.openposting = bidalitako mezu ireki bat
-articletypes.newswire = newswire
-articletypes.feature = azalakoa
-articletypes.topicspecial = gaiaz berezia
-articletypes.startspecial = berezia
-
-# Comment status values
-# missing (master value = "normal")
-commentstatus.normal = 
-
-
-
-########## error ##########
-error.htmltitle = Errakuntza
-error.title = Iep! Errakuntza bat gertatu da
-error.text = Ondoren datorren mezak agian ez dizu askorik lagunduko, baina seguraski <a href="mailto:{0}">{1}</a>koei bai.
-error.text2 = Mesedez, mezu bat bidali <a href="mailto:{0}">{1}</a>ra <font color="Red">gorriz agertzen den testuarekin</font> eta egiten ari zinenaren azalpen zehatzarekin. Eskerrik asko!
-
-usererror.htmltitle = Errakuntza datuetan
-usererror.title = Arranopola! Errakuntza bat gertatu da
-usererror.text = Sartu dituzun datuek ondoko errakuntza sortarazi dute:
-usererror.what_to_do = Mesedez, sakatu atzera botoia eta saiatu berriz
-
-# missing (master value = "The format of the media you uploaded is not supported")
-media.error.unsupportedformat = 
-# missing (master value = "The new password must be entered twice")
-user.error.missingpasswords = 
-# missing (master value = "The passwords are not equal")
-user.error.passwordmismatch = 
-# missing (master value = "A password must be entered")
-user.error.missingpassword = 
-# missing (master value = "Incorrect password")
-user.error.incorrectpassword = 
-
-
-
-
-########## infomessages ##########
-infomessage.htmltitle = Oharra
-# missing (master value = "Your request has been added to the queue.")
-infomessage.recipeAddedToQueue = 
+########## admin ##########\r
+# language: euskara / basque\r
+# $Id: admin_eu.properties,v 1.12.2.4 2004/11/21 22:07:12 zapata Exp $\r
+\r
+languagename = Euskara\r
+\r
+# general\r
+yes = bai\r
+no = ez\r
+dontcare = ez du axola\r
+all = dena\r
+month = hilabetea\r
+year = urtea\r
+file = fitxategia\r
+new = berria\r
+by = nork\r
+help = laguntza\r
+\r
+\r
+# actions\r
+insert = sartu\r
+save = gorde\r
+edit = aldatu\r
+delete = ezabatu\r
+add = gehitu\r
+filter = iragazi\r
+attach = atxeki\r
+list = zerrenda erakutsi\r
+back = atzera\r
+cancel = utzi\r
+preview = aurrebista\r
+reset = berrasieratu\r
+administer = administratu\r
+search = bilatu\r
+\r
+\r
+# special\r
+fileedit = fitxategia aldatu\r
+\r
+\r
+# records\r
+records = sarrerak\r
+show_from_to = {0}-(e)tik {1}-(e)ra bitarteko sarrerak erakusten\r
+no_matches_found = Ez da horrelako sarrerarik aurkitu!\r
+list.next = hurrengoa\r
+list.previous = aurrekoa\r
+\r
+system.status = Egoera:\r
+system.loggedin = Identifikatuta:\r
+\r
+# media - used by image, audio, video and other media\r
+media.urls = URLak\r
+media.created = sortua\r
+media.changed = aldatua\r
+media.published = argitaratua\r
+media.format = Formatua\r
+media.rights = Egile eskubideak\r
+media.type = Mota\r
+media.mediafolder = Baliabide mediatikoen karpeta\r
+media.title = Izenburua\r
+media.size = Tamaina\r
+media.description = Deskripzioa\r
+media.date = Data\r
+media.location = Jatorrizko lekua\r
+media.creator = Egilea\r
+media.keywords = Gako-hitzak\r
+media.comment = Komentarioa\r
+media.source = Jatorria\r
+media.is_published = Argitaratzeko prest\r
+media.icon = Ikonoa\r
+media.nr_of_media = Baliabide mediatikoen kopurua\r
+media.nr_of_media.submit = Kopurua aldatu\r
+media.comments = Komentarioak\r
+media.articles = Artikuluak\r
+\r
+medialist.search_text_in = Testua non bilatu\r
+\r
+\r
+# image\r
+image.htmltitle = Irudia\r
+imagelist.htmltitle = Irudien zerrenda\r
+\r
+\r
+# audio\r
+audio.htmltitle = Audioa\r
+audiolist.htmltitle = Audio zerrenda\r
+\r
+\r
+# video\r
+video.htmltitle = Bideoa\r
+videolist.htmltitle = Bideo zerrenda\r
+\r
+\r
+# other\r
+other_media.htmltitle = Beste baliabide mediatikoa\r
+other_medialist.htmltitle = Beste baliabide mediatikoen zerrenda\r
+\r
+\r
+# breaking\r
+breaking.htmltitle = Azken albisteak\r
+breaking.textinfo = (gehienez 5 lerro / 250 letra)\r
+breaking.id = id\r
+breaking.text = testua\r
+breaking.date = data\r
+\r
+breakinglist.htmltitle = Azken albisteen zerrenda\r
+\r
+\r
+# comment\r
+comment.htmltitle = Komentarioa\r
+comment.date = data\r
+comment.title = izenburua\r
+comment.published = argitaratuta\r
+comment.text = komentarioaren testua\r
+comment.address = helbidea\r
+comment.phone = telefonoa\r
+comment.email = posta elektronikoa\r
+comment.url = URL\r
+comment.creator = egilea\r
+comment.article = Artikuluarena\r
+comment.html = HTML da?\r
+comment.status = Egoera\r
+comment.language = Hizkuntza\r
+comment.allcomments = Komentario guztiak\r
+comment.comment = Barne-komentarioa\r
+comment.comment.info = (barne xederako)\r
+\r
+comment.operation.hide = ezkutatu\r
+comment.operation.unhide = agertarazi\r
+\r
+\r
+#commentlist\r
+commentlist.htmltitle = Komentarioen zerrenda\r
+commentlist.published = argitaratuta\r
+commentlist.hidden = ezkutua\r
+commentlist.allcomments = Artikulu honentzako komentario guztiak\r
+commentlist.search = bilatu!\r
+commentlist.activate = aldaketak eragin\r
+commentlist.order = hurrenkera\r
+commentlist.order.datedesc = berriena lehenengo\r
+commentlist.order.dateasc = zaharrena lehenengo\r
+commentlist.order.articletitle = artikuluaren izenburua\r
+\r
+commentsearch.field = Bilatu\r
+commentsearch.field.title = Izenburua\r
+commentsearch.field.creator = Egilea\r
+commentsearch.field.main_url = URL\r
+commentsearch.field.email = E-posta\r
+commentsearch.field.description = Deskripzioa\r
+commentsearch.value = Balorea\r
+\r
+commentsearch.publishedstate = Argitaraketa-egoera\r
+commentsearch.publishedstate.hidden = Ezkutua\r
+commentsearch.publishedstate.published = Argitaratua\r
+\r
+commentsearch.status = Egoera\r
+\r
+commentsearch.order = Hurrenkera\r
+commentsearch.order.datedesc = data (behera)\r
+commentsearch.order.dateasc = data (gora)\r
+commentsearch.order.articletitle = artikuluaren izenburua\r
+\r
+commentsearch.searchbutton = Bilatu\r
+\r
+\r
+# confirm\r
+confirm.htmltitle = Ezabaketa baieztatu\r
+confirm.really_delete = Sarrera hau ezabatu nahi duzu?\r
+confirm.text = Honek behin betiko ezabatuko du sarrera datu-basetik.\r
+\r
+\r
+# content\r
+content.htmltitle = Edukia\r
+content.owner = Jabea\r
+content.language = Hizkuntza\r
+content.articletype = Artikulu-mota\r
+content.topic = Gaia\r
+content.title = Izenburu luzea\r
+content.subtitle = Azpi-izenburua\r
+content.edittitle = Testuinguru izenburua\r
+content.location = Jatorrizko lekua\r
+content.creator = Egilea\r
+content.creator.email = Posta elektronikoa\r
+content.creator.url = Web\r
+content.creator.address = Helbidea\r
+content.creator.telephone = Telefonoa\r
+content.abstract = Deskripzio laburra\r
+content.content = Edukia\r
+content.html = HTML da?\r
+content.comment = Barne komentarioa\r
+content.internal = (barne xederako)\r
+content.keywords = Gako-hitzak\r
+content.lockedby = {0}-(e)k blokeatua\r
+content.lock = Blokeatu\r
+content.unlock = Desblokeatu\r
+content.forcelock = Blokeoa behartu\r
+\r
+content.attachments = Atxekiak\r
+content.images = Irudiak\r
+content.audio = Audioa\r
+content.video = Bideoa\r
+content.other = Beste baliabide mediatikoak\r
+content.media = Baliabide mediatikoak\r
+content.addimage = irudia gehitu\r
+content.uploadimage = irudia igo\r
+content.addaudio = audioa gehitu\r
+content.uploadaudio = audioa igo\r
+content.addvideo = bideoa gehitu\r
+content.uploadvideo = bideoa igo\r
+content.addother = beste baliabide mediatikoa gehitu\r
+content.uploadother = beste baliabide mediatikoa igo\r
+\r
+content.creationdate = data\r
+content.modificationdate = azken aldaketa\r
+content.status = Egoera\r
+content.type = Artikulu-mota\r
+content.import_date = sarreraren data\r
+content.lastchange_date = azken aldaketa\r
+content.create_date = data\r
+content.published = argitaratua\r
+content.comments = Komentarioak\r
+\r
+content.family = Aita eta Semeak\r
+content.children = Semeak\r
+content.viewchildren = ikusi\r
+content.parent = Gurasoa\r
+content.viewparent = ikusi\r
+content.clearparent = aukeraketa kendu\r
+content.selectparent = aukeratu\r
+\r
+content.operation.hide = ezkutatu\r
+content.operation.unhide = agertarazi\r
+content.operation.newswire = newswirea\r
+\r
+contentsearch.value = bilatu\r
+contentsearch.field = eremua\r
+contentsearch.field.title = Izenburua\r
+contentsearch.field.creator = Egilea\r
+contentsearch.field.contents = Edukiak\r
+contentsearch.field.creator_email = E-posta\r
+contentsearch.field.creator_main_url = Web helbidea\r
+\r
+contentsearch.publishedstate = argitaraketa-egoera\r
+contentsearch.publishedstate.hidden = ezkutua\r
+contentsearch.publishedstate.published = argitaratua\r
+\r
+contentsearch.articletype = artikulu-mota\r
+\r
+contentsearch.order = hurrenkera\r
+contentsearch.order.datedesc = Berriena lehenengo\r
+contentsearch.order.dateasc = Zaharrena lehenengo\r
+contentsearch.order.title = Izenburua\r
+contentsearch.order.creator = Egilea\r
+contentsearch.searchbutton = Bilatu\r
+\r
+\r
+#contentlist\r
+contentlist.htmltitle = Edukien zerrenda\r
+contentlist.comments = komentarioak\r
+contentlist.select = Aukeratu\r
+\r
+\r
+# language\r
+language.htmltitle = Hizkuntza\r
+language.id = Id\r
+language.name = hizkuntza\r
+language.code = Hizkuntza-kodea\r
+\r
+languagelist.htmltitle = Hizkuntzen zerrenda\r
+\r
+# login\r
+login.htmltitle = Sarrera\r
+login.info = Eremu hau baimendutako taldeentzat bakarrik da. Editore lanetan lagundu nahi baduzu, jar zaitez gurekin kontaktuan <a href="mailto:imc-euskalherria-editorial@lists.indymedia.org">imc-euskalherria-editorial@lists.indymedia.org</a> helbidean mesedez.\r
+login.title = erabiltzailea\r
+login.name = Erabiltzailea\r
+login.password = Pasahitza\r
+login.language = Hizkuntza\r
+login.submit = Ados\r
+\r
+\r
+# mediafolder\r
+mediafolder.htmltitle = Baliabide mediatikoen karpeta\r
+mediafolder.id = id\r
+mediafolder.date = data\r
+mediafolder.name = izena\r
+mediafolder.location = jatorrizko lekua\r
+mediafolder.keywords = gako-hitzak\r
+mediafolder.comment = komentarioa\r
+\r
+mediafolderlist.htmltitle = Baliabide mediatikoen karpeten zerrenda\r
+\r
+\r
+# message\r
+message.htmltitle = Mezuak\r
+message.id = id\r
+message.date = data\r
+message.title = izenburua\r
+message.creator = Egilea\r
+message.text = testua\r
+message.textinfo = (gehienez 5 lerro / 250 letra)\r
+\r
+messagelist.htmltitle = Mezuen zerrenda\r
+\r
+# admin start page\r
+start.htmltitle = Administrazioa\r
+\r
+start.content.new = artikulu berriak\r
+start.show = Erakutsi\r
+start.comment.open_by_id = komentario-ireki zenbakia:\r
+start.content.open_by_id = artikulu-ireki zenbakia:\r
+\r
+start.content.hidden = artikulu ezkutukoak\r
+start.content.not_published = argitaratzeke dauden artikuluak\r
+start.content.with_media = baliabide mediatikoekin\r
+start.content.last_changes = azken aldaketak\r
+start.content.with_comments = barne xederako komentarioekin\r
+start.content.all = Artikulu guztiak\r
+start.content.search = bilatu\r
+\r
+start.allarticlesoftype = {0}-motatako artikulu guztiak\r
+start.allcommentswithstatus = {0}\r
+\r
+start.producers.title = Eskuz ekoiztu\r
+start.producers.produceAllNew = Berri guztia ekoiztu\r
+start.producers.recipe.allnew = Berri guztia ekoiztu\r
+\r
+start.producers.advanced = Aukera arreratuak (kontuz honekin!)\r
+\r
+start.administer.title = ADMINISTRATU\r
+start.administer.comments = komentarioak\r
+\r
+start.comments.title = KOMENTARIOAK\r
+\r
+start.breaking.title = AZKEN ALBISTEAK\r
+start.articles.title = ARTIKULUAK\r
+start.fileedit.includes.title = include fitxategiak aldatu\r
+start.addandedit.title = GEHITU / ALDATU\r
+start.extra.title = EXTRA\r
+start.search.title = BILAKETA\r
+start.other_media.title = BESTE MEDIOEN FITXATEGIAK\r
+start.images.title = IRUDIAK\r
+start.images.open_by_id = irudi-ireki zenbakia:\r
+start.video.title = BIDEO FITXATEGIAK\r
+start.audio.title = AUDIO FITXATEGIAK\r
+start.media.title = MEDIA\r
+start.mediafolder.title = BALIABIDE MEDIATIKOEN ZERRENDA\r
+start.languages.title = IZENBURUA\r
+start.imcs.title = MIGak\r
+start.messageboard.title = Barneko mezuak\r
+start.messageboard.no_messages = ez dago mezurik\r
+\r
+start.superusermenu = Goi-erabiltzaileentzako funtzioak (kontuz honekin!)\r
+\r
+\r
+# topic\r
+\r
+topic.htmltitle = Gaia\r
+\r
+topic.id = id\r
+topic.title = Izena\r
+topic.description = deskripzioa\r
+topic.filename = Fitxategiaren izena\r
+topic.main_url = Informazio nagusiko orria\r
+topic.archive_url = Fitxategiaren URLa\r
+\r
+topiclist.htmltitle = Gaien zerrenda\r
+\r
+\r
+# users\r
+user.htmltitle = Erabiltzailea\r
+user.login = erabiltzailea\r
+user.ownpassword = Zure pasahitza\r
+user.oldpassword = Pasahitz zaharra\r
+user.password = Pasahitza\r
+user.password2 = Pasahitza (berriro)\r
+user.admin = administratzailea\r
+user.is_disabled = Ezgaituta?\r
+user.creationdate = Sorrera-data\r
+user.lastlogindate = Azken sarketa\r
+user.email = Posta elektronikoa\r
+user.comment = Oharra\r
+user.profile = Profila\r
+\r
+\r
+\r
+\r
+userlist.htmltitle = Erabiltzaileen zerrenda\r
+\r
+\r
+#articletype\r
+articletype.htmltitle = Artikulu-motak\r
+articletype.id = Id\r
+articletype.name = Izena\r
+\r
+articletypelist.htmltitle = Artikulu-moten zerrenda\r
+\r
+# mediatypes\r
+mediatypelist.htmltitle = Media-motak kudeatu\r
+mediatype.id = Id\r
+mediatype.name = Izena\r
+mediatype.htmltitle = Media-mota\r
+mediatype.mimetype = MIME-mota\r
+mediatype.classname = Klase izena\r
+mediatype.tablename = Taula izena\r
+\r
+#commentstatus\r
+commentstatus.htmltitle = Komentarioen egoera\r
+commentstatus.id = Id\r
+commentstatus.name = Izena\r
+\r
+commentstatuslist.htmltitle = Komentarioen egoeraren zerrenda\r
+\r
+\r
+\r
+#file editing\r
+fileedit.htmltitle = Fitxategia aldatu\r
+fileedit.filename = Fitxategiaren izena\r
+fileedit.subdirectory = Azpidirektorioa\r
+\r
+fileeditlist.htmltitle = Fitxategien aldaketak\r
+fileeditlist.filename = Fitxategiaren izena\r
+fileeditlist.dirname = Azpidirektorioa\r
+\r
+\r
+#producers\r
+producer.producer = Ekoizlearen izena\r
+producer.verb.name = Lanaren izena\r
+producer.verb.description = Lanaren deskripzioa\r
+producer.verb.enqueue = Eskatu\r
+\r
+producer.job.name = Lana\r
+producer.job.status = Egoera\r
+producer.job.date = azken aldaketa\r
+producer.job.empty = Ilada hutsik dago\r
+producer.job.runningtime = Denbora exekuzioan\r
+\r
+producer.jobqueue.canceljobs = Aukeratutako lanak ezeztatu\r
+producer.jobqueue.cancelalljobs = Egiteke dauden lan guztiak ezeztatu\r
+producer.jobqueue.title = Oraingo lanak\r
+producer.jobqueue.refresh = birkargatu\r
+producer.producerlist.title = Lan berri bat gehitu\r
+\r
+producerqueue.htmltitle = Eskuz ekoiztu\r
+\r
+\r
+#superusermenu\r
+superusermenu.htmltitle = Aukera aurreratuak\r
+superusermenu.manage = KUDEATU\r
+superusermenu.topics = Gaien kudeaketa\r
+superusermenu.articletypes = Artikulu-moten kudeaketa\r
+superusermenu.mediatypes = Media-motak\r
+superusermenu.comment_statuses = Komentarioen egoeraren kudeaketa\r
+superusermenu.users = Erabiltzaileen kudeaketa\r
+superusermenu.languages = Hizkuntzen kudeaketa\r
+superusermenu.abuse = gehiegikerien aurkako neurriak eragin\r
+superusermenu.imcs = MIGen zerrendaren kudeaketa (zaharkitua)\r
+\r
+\r
+#abuse\r
+abuse.htmltitle = gehiegikerien aurkako neurriak\r
+\r
+abuse.setting = Aukera\r
+abuse.value = Balioa\r
+\r
+abuse.disableopenpostings = bidalketa-irekia itxi\r
+abuse.openpostingpassword = bidalketa-irekientzako pasahitza eskatu\r
+abuse.logpostings = bidalketa-irekien IPak gorde\r
+abuse.logsize = Gordetako log-aren tamaina\r
+abuse.cookies = Blokeatutako erabiltzaileekin cookie-ak erabili\r
+abuse.articleaction = Blokeatutako artikuluekin egin beharrekoa\r
+abuse.commentaction = Blokeatutako komentarioekin egin beharrekoa\r
+\r
+abuse.showlog = IPen log-a erakutsi\r
+abuse.showfilters = Iragazkiak kudeatu\r
+\r
+abuse.log.time = Ordua\r
+abuse.log.address = IP zenbakia\r
+abuse.log.object = Objektua\r
+abuse.log.browser = Nabigatzaiela\r
+abuse.log.filtertype = Iragazki-mota\r
+abuse.log.filterexpression = Espresioa\r
+\r
+abuse.filters = Iragazkiak\r
+abuse.filters.movedown = bera\r
+abuse.filters.moveup = gora\r
+\r
+abuse.filter.type = Motak\r
+abuse.filter.expression = Espresioa\r
+abuse.filter.articleaction = Artikulua\r
+abuse.filter.commentaction = Komentarioa\r
+abuse.filter.comments = Komentarioak (barne xederako)\r
+abuse.filter.lasthit = Azken hit-a\r
+abuse.filter.htmltitle = Iragazkia aldatu\r
+\r
+abuse.filtertype.ip = IP Zenbakia\r
+abuse.filtertype.regexp = Espresio erregularra\r
+abuse.filtertype.useragent = Nabigatzailea\r
+\r
+abuse.filtererror.title = Errakuntza:\r
+abuse.filtererror.invalidtype = Iragazki-mota okerra\r
+abuse.filtererror.invalidexpression = Mota honentzako espresio okerra\r
+\r
+abuse.filters.htmltitle = Gehiegikerien aurkako iragazki arauak\r
+abuse.log.htmltitle = Gehiegikerien aurkako bidalketa-irekien log-a\r
+\r
+# head\r
+head.start = hasiera\r
+head.logout = irten\r
+head.changepassword = pasahitza\r
+head.help = laguntza\r
+head.search = bilatu\r
+head.logged_in = erregistraturik zaude\r
+\r
+# foot\r
+foot.top = gora\r
+\r
+\r
+########## dynamic values ##########\r
+\r
+# (users can add new types, how to translate these)\r
+# suggestion if not in bundle use value as Text\r
+\r
+\r
+# Article types\r
+articletypes.openposting = bidalketa-irekia\r
+articletypes.newswire = newswirea\r
+articletypes.feature = azalekoa\r
+articletypes.topicspecial = gaiko berezia\r
+articletypes.startspecial = azaleko berezia\r
+\r
+# Comment status values\r
+commentstatus.normal = normala\r
+\r
+\r
+\r
+########## error ##########\r
+error.htmltitle = Errakuntza\r
+error.title = Iep! Errakuntza bat gertatu da\r
+error.text = Ondoren datorren mezuak agian ez dizu askorik lagunduko, baina seguraski <a href="mailto:{0}">{1}</a>koei bai.\r
+error.text2 = Mesedez, bidali posta elektronikoko mezu bat <a href="mailto:{0}">{1}</a>ra <font color="Red">gorriz agertzen den testuarekin</font> eta egiten ari zinenaren azalpenarekin (fitxategia igotzen, artikulua bidaltzen, komentarioa bidaltzen, bilaketa egiten...). Eskerrik asko!\r
+\r
+usererror.htmltitle = Errakuntza datuetan\r
+usererror.title = Arranopola! Errakuntza bat gertatu da\r
+usererror.text = Sartu dituzun datuek ondoko errakuntza sortarazi dute:\r
+usererror.what_to_do = Mesedez, sakatu atzera botoia eta saiatu berriz\r
+\r
+media.error.unsupportedformat = Igo duzun baliabide mediatikoaren formatuarekin ez dugu lan egiten\r
+user.error.missingpasswords = Pasahitz berria birritan sartu beharra dago\r
+user.error.passwordmismatch = Pasahitzak ez dira berdinak\r
+user.error.missingpassword = Pasahitz bat sartu beharra dago\r
+user.error.incorrectpassword = Pasahitza okerra da\r
+\r
+\r
+########## infomessages ##########\r
+infomessage.htmltitle = Oharra\r
+infomessage.recipeAddedToQueue = Zure eskaria ilarara gehitu da\r
diff --git a/bundles/admin_ro.properties b/bundles/admin_ro.properties
new file mode 100755 (executable)
index 0000000..365e75a
--- /dev/null
@@ -0,0 +1,530 @@
+########## admin ##########\r
+# language: romanian\r
+# $Id: admin_ro.properties,v 1.2.2.1 2004/11/21 22:07:12 zapata Exp $\r
+\r
+languagename=Romana\r
+\r
+# general\r
+yes=da\r
+no=nu\r
+dontcare=nuconteaza\r
+all=tot\r
+month=luna\r
+year=an\r
+file=fisier\r
+new=nou\r
+by=de\r
+help=ajutor\r
+\r
+\r
+# actions\r
+insert=insert\r
+save=salveaza\r
+edit=redacteaza\r
+delete=sterge\r
+add=adauga\r
+filter=filtreaza\r
+attach=ataseaza\r
+list=browse\r
+back=inapoi\r
+cancel=canceleaza\r
+preview=preview\r
+reset=reset\r
+administer=administreaza\r
+search=cauta\r
+\r
+\r
+# special\r
+fileedit=redactareFisier\r
+\r
+\r
+# records\r
+records=entries\r
+show_from_to=arata de la {0} la {1}\r
+no_matches_found=No matching entries!\r
+list.next=urmatorul\r
+list.previous=precedentul\r
+\r
+\r
+# media - used by image, audio, video and other media\r
+media.created=creat\r
+media.changed=ultima modificare\r
+media.published=publicat\r
+media.format=format\r
+media.rights=statut copyright\r
+media.type=tip\r
+media.mediafolder=dosar Media\r
+media.title=titlu\r
+media.size=marime\r
+media.description=descriere\r
+media.date=data\r
+media.location=loc\r
+media.creator=autor\r
+media.keywords=keywords\r
+media.comment=remarci (pentru us intern)\r
+media.source=sursa\r
+media.is_published=publicat\r
+media.icon=icon\r
+media.nr_of_media=Number of Media Items (max 20)\r
+media.nr_of_media.submit=define number\r
+media.comments=Comentarii\r
+media.articles=Articole\r
+\r
+medialist.search_text_in=Cauta text in\r
+\r
+\r
+# image\r
+image.htmltitle=Imagine\r
+imagelist.htmltitle=Images overview\r
+\r
+\r
+# audio\r
+audio.htmltitle=Audio\r
+audiolist.htmltitle=Audio overview\r
+\r
+\r
+# video\r
+video.htmltitle=Video\r
+videolist.htmltitle=Video overview\r
+\r
+\r
+# other\r
+other_media.htmltitle=Alta media\r
+other_medialist.htmltitle=Other media overview\r
+\r
+\r
+# breaking\r
+breaking.htmltitle=Ultimile stiri\r
+breaking.textinfo=(max. 5 linii / 250 caractere)\r
+breaking.id = id\r
+breaking.text=text\r
+breaking.date=data\r
+\r
+breakinglist.htmltitle=Breaking news overview\r
+\r
+\r
+# comment\r
+comment.htmltitle=Comment\r
+comment.date=Data\r
+comment.title=Titlu\r
+comment.published=Publicat\r
+comment.text=Comenteaza textul\r
+comment.address=Adresa\r
+comment.phone=Telefon\r
+comment.email=Email \r
+comment.url=Url\r
+comment.creator=Autor\r
+comment.article=Articol\r
+comment.html=HTML \r
+comment.status=Statut\r
+comment.language=Limba\r
+comment.allcomments=Toate comentariile\r
+\r
+comment.operation.hide=ascunde\r
+comment.operation.unhide=neascunde\r
+\r
+\r
+#commentlist\r
+commentlist.htmltitle=comentarii\r
+commentlist.published=publicat\r
+commentlist.hidden=ascuns\r
+commentlist.allcomments=Toate comentariile despre acest articol\r
+commentlist.search=go!\r
+commentlist.activate = activeaza schimbarile\r
+commentlist.order = ordoneaza\r
+commentlist.order.datedesc= data (desc.)\r
+commentlist.order.dateasc= data (asc.)\r
+commentlist.order.articletitle= titlul articolui\r
+\r
+commentsearch.field = Cauta \r
+commentsearch.field.title = Titlu\r
+commentsearch.field.creator = Autor\r
+commentsearch.field.main_url = Url\r
+commentsearch.field.email = Email\r
+commentsearch.field.description = Descriere\r
+commentsearch.value = Value \r
+\r
+commentsearch.publishedstate = Statut publicat\r
+commentsearch.publishedstate.hidden = Ascuns\r
+commentsearch.publishedstate.published = Publicat\r
+\r
+commentsearch.status = Statut\r
+\r
+commentsearch.order = Ordine\r
+commentsearch.order.datedesc= data (desc.)\r
+commentsearch.order.dateasc= data (asc.)\r
+commentsearch.order.articletitle= titlul articolui\r
+\r
+commentsearch.searchbutton = Cauta\r
+\r
+\r
+# confirm\r
+confirm.htmltitle=confirmare de stergere\r
+confirm.really_delete=Esti sigur ca vrei sa stergi acest articol?\r
+confirm.text=Aceasta operatiune este ireversibila.\r
+\r
+\r
+# content\r
+content.htmltitle=Articol \r
+content.owner=Proprietar\r
+content.language=Limba \r
+content.articletype=Tip de articol\r
+content.topic=Subiect\r
+content.title=Titlul Lung\r
+content.subtitle=Titlul scurt\r
+content.edittitle=Titlul de context\r
+content.location=Loc\r
+content.creator=Autor\r
+content.creator.email=E-mail\r
+content.creator.url=Web address\r
+content.creator.address=Adresa\r
+content.creator.telephone=Telefon\r
+content.abstract=Abstract\r
+content.content=Continut\r
+content.html=HTML\r
+content.comment=Comentar intern\r
+content.internal=(intern)\r
+\r
+content.attachments=Atasamente\r
+content.images=Imagini\r
+content.audio=Audio\r
+content.video=Video\r
+content.other=Alta media\r
+content.media=Media \r
+content.addimage=adauga imagine\r
+content.uploadimage=incaraca imagine\r
+content.addaudio=adauga audio\r
+content.uploadaudio=incarca audio\r
+content.addvideo=adauga video\r
+content.uploadvideo=incarca video\r
+content.addother=adauga alta media\r
+content.uploadother=incarca alta media\r
+\r
+content.creationdate=data \r
+content.modificationdate=ultima schimbare\r
+content.status=Statut\r
+content.type=Tip de articol\r
+content.import_date=Data de importare\r
+content.lastchange_date=Ultima modificare\r
+content.create_date=Data\r
+content.published=publicat\r
+content.comments=comentarii\r
+\r
+content.family=Copii si Parinti\r
+content.children=Copii\r
+content.viewchildren=view \r
+content.parent=Parinte\r
+content.viewparent=view\r
+content.clearparent=de-selecteaza\r
+content.selectparent=selecteaza\r
+\r
+content.operation.hide=ascunde\r
+content.operation.unhide=ne-ascunde\r
+content.operation.newswire=newswire \r
+\r
+contentsearch.value = cauta\r
+contentsearch.field = field\r
+contentsearch.field.title = Titlu\r
+contentsearch.field.creator = Autor\r
+contentsearch.field.contents=Continut\r
+contentsearch.field.creator_email = Email\r
+contentsearch.field.creator_main_url = Web address\r
+\r
+contentsearch.publishedstate = statut de publicare\r
+contentsearch.publishedstate.hidden=ascuns\r
+contentsearch.publishedstate.published=publicat\r
+\r
+contentsearch.articletype = tip de articol\r
+\r
+contentsearch.order = in ordine de\r
+contentsearch.order.datedesc=cel mai nou primul\r
+contentsearch.order.dateasc=cel mai vechi primul\r
+contentsearch.order.title=Titlu\r
+contentsearch.order.creator=Aautor\r
+contentsearch.searchbutton=Cauta\r
+\r
+\r
+#contentlist\r
+contentlist.htmltitle=Articole\r
+contentlist.comments=Comentarii\r
+contentlist.select=Selecteaza\r
+\r
+\r
+# language\r
+language.htmltitle=Llimba\r
+language.id=Id \r
+language.name=Limba\r
+language.code=Limbaj cod\r
+\r
+languagelist.htmltitle=Limbi\r
+\r
+# login\r
+login.htmltitle=login\r
+login.info=Aceasta parte este accesibila doar celor care sint autorizati. Daca doresti sa participi in grupul editorial, contacteaza-ne la {0}. \r
+login.title=login\r
+login.name=Login\r
+login.password=Parola\r
+login.language=Limba\r
+login.submit=  OK\r
+\r
+\r
+# mediafolder\r
+mediafolder.htmltitle=dosarmedia\r
+mediafolder.id=id\r
+mediafolder.date=data\r
+mediafolder.name=nume\r
+mediafolder.location=loc\r
+mediafolder.keywords=keywords\r
+mediafolder.comment=comentariu\r
+\r
+mediafolderlist.htmltitle=media folder list\r
+\r
+\r
+# message\r
+message.htmltitle=messages\r
+message.id=id\r
+message.date=data\r
+message.title=titlu\r
+message.creator=autor\r
+message.text=text\r
+message.textinfo=(max. 5 linii / 250 caractere)\r
+\r
+messagelist.htmltitle=lista de mesaje\r
+\r
+# admin start page\r
+start.htmltitle=admin\r
+\r
+start.content.new=articol nou\r
+start.show=arata\r
+start.comment.open_by_id=open comment #\r
+start.content.open_by_id=open article #\r
+\r
+start.content.hidden=arata toate articolele ascunse\r
+start.content.not_published=articole inca nepublicate\r
+start.content.with_media=cu media\r
+start.content.last_changes=ultimele schimbari\r
+start.content.with_comments=cu comentarii interne\r
+start.content.all=toate articolele\r
+start.content.search=cauta\r
+\r
+start.allarticlesoftype={0}\r
+start.allcommentswithstatus={0}\r
+\r
+start.producers.title=GENEREAZA MANUAL\r
+start.producers.produceAllNew=genereaza totul nou\r
+start.producers.recipe.allnew=genereaza totul nou\r
+\r
+start.producers.advanced=pagina avansata (utilizati cu grija!)\r
+\r
+start.administer.title=ADMINISTREAZA\r
+start.administer.comments=comentarii\r
+\r
+start.comments.title=COMENTARII\r
+\r
+start.breaking.title=ultimele stiri\r
+start.articles.title=ARTICOLE\r
+start.fileedit.includes.title=edit include files\r
+start.addandedit.title=ADD / EDIT\r
+start.extra.title=EXTRA\r
+start.search.title=SEARCH\r
+start.other_media.title=alta media\r
+start.images.title=poze\r
+start.video.title=video\r
+start.audio.title=audio\r
+start.media.title=MEDIA\r
+start.mediafolder.title=dosarmedia\r
+start.languages.title=LIMBI\r
+start.imcs.title=IMCS\r
+start.messageboard.title=MESSAGEBOARD\r
+start.messageboard.no_messages=no messages\r
+\r
+start.superusermenu=super-user functions (use with care!)\r
+\r
+\r
+# topic\r
+\r
+topic.htmltitle=topic\r
+\r
+topic.id=id\r
+topic.title=nume\r
+topic.description=descriere\r
+topic.filename=numefisier\r
+topic.main_url=main infopage\r
+topic.archive_url=url arhiva\r
+\r
+topiclist.htmltitle=topiclist\r
+\r
+\r
+# users\r
+user.htmltitle=User\r
+user.login=Login\r
+user.ownpassword=Your own password\r
+user.oldpassword=Old password\r
+user.password=Password\r
+user.password2=Password (confirmation)\r
+user.admin=Admin\r
+\r
+userlist.htmltitle=Users\r
+\r
+\r
+#articletype\r
+articletype.htmltitle=Tip de articol\r
+articletype.id=id\r
+articletype.name=Name\r
+\r
+articletypelist.htmltitle=Tipuri de articole\r
+\r
+\r
+\r
+#commentstatus\r
+commentstatus.htmltitle=Statut comentar\r
+commentstatus.id=id\r
+commentstatus.name=Nume\r
+\r
+commentstatuslist.htmltitle=Comment status values\r
+\r
+\r
+\r
+#file editing\r
+fileedit.htmltitle = Editeza fisier\r
+fileedit.filename = Numefisier\r
+fileedit.subdirectory = Subdirectory\r
+\r
+fileeditlist.htmltitle = Fisier cu posibilitate de editare\r
+fileeditlist.filename = Filename\r
+fileeditlist.dirname = Subdirectory\r
+\r
+\r
+#producers\r
+producer.producer = Producer name\r
+producer.verb.name = Task name\r
+producer.verb.description = Task description\r
+producer.verb.enqueue = enqueue\r
+\r
+producer.job.name = Job\r
+producer.job.status = Statut\r
+producer.job.date = Ultima schimbare\r
+producer.job.empty = Queue is empty\r
+producer.job.runningtime = Running time\r
+\r
+producer.jobqueue.canceljobs = Cancel selected jobs\r
+producer.jobqueue.cancelalljobs = Cancel all pending jobs\r
+producer.jobqueue.title = Current jobs\r
+producer.jobqueue.refresh = refresh\r
+producer.producerlist.title = Add a new job\r
+\r
+producerqueue.htmltitle = Genereaza manual\r
+\r
+\r
+#superusermenu\r
+superusermenu.htmltitle = Super-user functions\r
+superusermenu.manage = MANAGE\r
+superusermenu.topics = subiecte\r
+superusermenu.articletypes =  tipuri de articole\r
+superusermenu.comment_statuses =  comment status values\r
+superusermenu.users =  users\r
+superusermenu.languages =  \r
+superusermenu.abuse = apply anti-abuse measures\r
+superusermenu.imcs =  IMCS (obsolete)\r
+\r
+\r
+#abuse\r
+abuse.htmltitle = anti-abuse measures\r
+\r
+abuse.setting = Setting\r
+abuse.value = Value\r
+\r
+abuse.disableopenpostings=Turn off open posting\r
+abuse.openpostingpassword=Require a password for open postings\r
+abuse.logpostings=Log IPs for open postings\r
+abuse.logsize=Logging buffer size\r
+abuse.cookies=Use cookies for blocked users\r
+abuse.articleaction=Action for blocked article\r
+abuse.commentaction=Action for blocked comment\r
+\r
+abuse.showlog=Show the IP log\r
+abuse.showfilters=Manage filters\r
+\r
+abuse.log.time=Time\r
+abuse.log.address=IP number\r
+abuse.log.object=Object\r
+abuse.log.browser=Browser\r
+abuse.log.filtertype=Filter type\r
+abuse.log.filterexpression=Expression\r
+\r
+abuse.filters = Filters\r
+abuse.filters.movedown = move down\r
+abuse.filters.moveup = move up\r
+\r
+abuse.filter.type = Type\r
+abuse.filter.expression = Expression\r
+abuse.filter.articleaction = Article \r
+abuse.filter.commentaction = Comment \r
+abuse.filter.comments = Comments (internal usage)\r
+abuse.filter.lasthit = Last hit\r
+abuse.filter.htmltitle = Edit filter\r
+\r
+abuse.filtertype.ip = IP Number\r
+abuse.filtertype.regexp = Regular expression\r
+\r
+abuse.filtererror.title = Error:\r
+abuse.filtererror.invalidtype = Invalid filter type\r
+abuse.filtererror.invalidexpression = Invalid expression for this type\r
+\r
+abuse.filters.htmltitle = Anti-abuse filter rules\r
+abuse.log.htmltitle = Anti-abuse open posting log\r
+\r
+# head\r
+head.start=start\r
+head.logout=logout\r
+head.changepassword=password\r
+head.help=help\r
+head.search=search\r
+head.logged_in=logged in\r
+\r
+# foot\r
+foot.top=top\r
+\r
+\r
+########## dynamic values ##########\r
+\r
+# (users can add new types, how to translate these)\r
+# suggestion if not in bundle use value as Text\r
+\r
+\r
+# Article types\r
+articletypes.openposting=Open posting\r
+articletypes.newswire=Newswire\r
+articletypes.feature=Feature\r
+articletypes.topicspecial=Topic-special\r
+articletypes.startspecial=Startpage-special\r
+\r
+# Comment status values\r
+commentstatus.normal=normal\r
+\r
+\r
+\r
+########## error ##########\r
+error.htmltitle=the system caused an error\r
+error.title=The system caused an error\r
+error.text=This can happen. Even if the following error message is not be comprehensible for you, <br>it might be helpful to <a href="mailto:{0}">{1}</a>:\r
+error.text2=So please send an e-mail with the <font color="Red">red text</font> and detailed information regarding the events that led to this error to <a href="mailto:{0}">{1}</a>. Thanks!\r
+\r
+usererror.htmltitle=Input error\r
+usererror.title=Input error\r
+usererror.text=Your input caused the following error:\r
+usererror.what_to_do=Please press the back button and try it again\r
+\r
+media.error.unsupportedformat=The format of the media you uploaded is not supported\r
+user.error.missingpasswords=The new password must be entered twice\r
+user.error.passwordmismatch=The passwords are not equal\r
+user.error.missingpassword=A password must be entered\r
+user.error.incorrectpassword= Incorrect password\r
+\r
+\r
+\r
+\r
+########## infomessages ##########\r
+infomessage.htmltitle = Information\r
+infomessage.recipeAddedToQueue = Your request has been added to the queue.\r
+\r
index f4e3d86..0bdad5e 100755 (executable)
@@ -4,3 +4,4 @@ INSERT INTO "article_type" VALUES (1,'newswire');
 INSERT INTO "article_type" VALUES (2,'feature');
 INSERT INTO "article_type" VALUES (3,'topicspecial');
 INSERT INTO "article_type" VALUES (4,'startspecial');
+INSERT INTO "article_type" VALUES (5,'translation');
index 6cf6a0b..9af2e5a 100755 (executable)
@@ -2,3 +2,4 @@
 -- \connect - postgres
 INSERT INTO "language" VALUES (0,'deutsch','de');
 INSERT INTO "language" VALUES (1,'english','en');
+INSERT INTO "language" VALUES (2,'other','ot');
diff --git a/doc/CODESTRUCTURE b/doc/CODESTRUCTURE
deleted file mode 100755 (executable)
index d89260e..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
--------------------------------------------------------------------------------
-
-A short intro to the code-structure of Mir
-
--------------------------------------------------------------------------------
-
-In the java-source tree you will find the following:
-
- - two classes (OpenMir and Mir)
- - two packages (mir and mircoders)
-
-
-Servlets:
--------------------------------------------------------------------------------
-
-Looking from the request of a client browser onto MIR, the http-request is
-passed via Apache/Tomcat to either Mir.class or OpenMir.class. Mir.class
-handles all request that deal with internal administration tasks of MIR.
-OpenMir is the Servlet that deals with all open tasks: adding comments or
-articles/media to the system.
-
-These servlets don't do much but dispatching the tasks to an underlying
-code level, called ServletModules. OpenMir.class is basically a special
-case of Mir.class, no authentication is needed, and only two underlying
-ServletModule are used.
-
-The following explanation is about how requests are passed through, and
-responses to the client-browser are generated. The request has to pass
-through up to four levels of code (and from there asking the database),
-until it collected all the necessary data or performed all necessary
-tasks, to be able to respond.
-
-
-ServletModules:
--------------------------------------------------------------------------------
-
-The ServletModules are called via reflection java-api. The http-request
-parameter "module=XXX" and "do=YYY" are evaluated. A method
-YYY(HttpRequest,HttpResponse) is called in ServletModuleXXX.
-
-A common mistake for those new to Java is to look for usage of a class in 
-the code by doing a "grep -r ClassName" or something like that. In this 
-case, grep -r ServletModuleImages for example will turn up nothing except 
-for ServletModuleImages itself.. that is because of reflection as 
-explained above.
-
-The media handlers in mir.media.* work the same way as well. 
-
- Database/Entity:
--------------------------------------------------------------------------------
-- db: singeltons, object-representation of db-table, *low-level* access, 
-generating entities, does all the dirty JDBC work. There is a Database 
-Class for every table in the DB.
-
-If an Entity wants to store itself in the media table, it has to have a 
-storage object of type DatabaseMedia....
-
-When you ask a storage object to get something, it hands back an Entity.
-[through Database*.selectByWhereClause(), selectById().]
-
-- entity: representation of row. Contains the contents of "select * from
-dbname where id=rowid" in a HashMap. accessible via
-Entity.getValue("keyname"). One can do Entity.setValue(...,
-Entity.update() which syncs the Hash with the DB row and Entity.insert()  
-to insert the HashMap as a new row, etc... basically high level DB access.
-The text component of an article is an entity (EntityContent, a row from
-the content table.) In short this is how we fetch content (whatever that
-may be: actual data, media meta-data, media_types, etc..) from the DB and
-write to the DB. Everything has to be reprented as an Entity.
-
-All Entities must have a StorageObject (theStorage) which is a Database
-object of the appropriate type. it is the connection between the entity
-data and the DB table itself. The only way to get an Entity other than
-asking a storage object to fetch one is to construct one by passing the
-storage object to the Entity Konstruktor.
-
-There is also EntityList, a list of entities..
-
-Modules:
--------------------------------------------------------------------------------
-
-- This one is a little grey... It's pretty much a wrapper around Database 
-and Entity combined, so it's a half level higher up or so. It's not always 
-necessary to use/have a Module either.. A usage example: you can do
-ModuleName.getByWhereClause() and it returns a list of Entities that match 
-the query. Like entities you must have a StorageObject to access the DB. 
-but unlike Entity, you can start out without one. Modules use Entity and 
-Database objects internally. [Actually it uses Database object internally 
-and returns Entitys...]
-
-Also I believe the intention was/is that it should be used in place of 
-Entity for any *logic* that would normally have to into an Entity as 
-Entity should be free of a case specific logic in theory. But that's not
-always true if you use EntityImages as an example, but that seems to be 
-because EntityImages needs low-level DB connections.
-
-Producer
--------------------------------------------------------------------------------
-
-Well, what makes Mir different than other Content Management Systems is
-that it does not generate the content pages dynamically or use simple
-caching methods. Rather it generates static .[s]html files exclusively.  
-This makes mir very fast under high viewing loads as it does not use
-servlets for this at all. It also makes it very easy to mirror as the
-mirrors do not have to run any Mir code, they only have to have a static
-webserver. In fact the first site to use Mir, germany.indymedia.org is on
-a whole other machine on another continent than the machine that
-*produces* the static files. Germany.indymedia.org already has 3 mirrors.
-
-The mircoders.producer.* classes are responsible for creating these static 
-.html files and the filesystem structure that they reside in. This 
-includes files that are article summaries and files that are the whole 
-article themselves. Some media types also require Producers.
-
-If the main content *viewing* server is on another host, the FS tree is
-then rsync'ed to the viewing host.
-
-The Producers are called exclusively from the ServletModules in
-mircoders.servlet.*. They are called when a new article/comment is added,
-or when an administrator/moderator makes modifications to the site or when
-a manual update is desired. The method "handle()" is the one that does all
-work it takes parameters that tell it to force update all files even if
-their contents is unchanged, etc.. some Producers take an article ID as an
-argument telling them to create the html page representing the article and
-any summary pages that might be changed due to the addition of the
-article.
-
-Producers of course use Entities, Database, MediaHandler and Module
-objects internally.
-
-A dB field called is_produced is used to determine wether or not an Object 
-needs to be produced.
-
-Oh and before I forget, it generates the pages based on a template. It 
-uses the Freemarker templating system. Doc on freemarker is available at 
-freemarker.sourceforge.net I believe. 
-
-TODO: In theory it would be cool if we could abstract the output mechanism
-further to use other types of templates and to generate content other than
-HTML (like WAP for example). 
-
-Media Handlers
--------------------------------------------------------------------------------
-They are kind of helper classes to deal with different representations of
-media types. They are called via the java reflection API. The class names 
-are resolved through the media_type table. See 
-source/mir/media/MirMedia.java for documentation.
-
-Helper classes
--------------------------------------------------------------------------------
-mir.misc.* (source/mir/misc/*) contains a bunch of classes that do Regexp, 
-file handling and those sorts of things. Always look here first before 
-writing such a thing.
diff --git a/doc/CODINGSTYLE b/doc/CODINGSTYLE
deleted file mode 100755 (executable)
index 654af7a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-last changed: $Date: 2002/12/08 07:05:56 $
-------------------------
-
-please us spaces not tabs for indents. all indents should be 2 spaces wide.
-
-If you use the vim editor, below is a good .vimrc entry for java files that
-makes all tabs appear 2 chars. wide and makes indenting using the TAB key create
-2 real spaces. It also sets the shiftwidth to 2 spaces.
-
-in your .vimrc add the following:
-
-autocmd FileType java source /path/to/file/.vimrc.java
-
-create .vimrc.java and add the following:
-
-set tabstop=2
-set shiftwidth=2
-set expandtab
-
-if you can, please try to make your code terminal friendly so a line should
-not be more than 80 characters wide pls. Not all mir code is like this and it
-is not required (well what really is required?)
-
-For java code, class names usually begin with a capital letter. e.g
-StringUtils.java. Names for variables and methods should begin with a lower case
-letter. However, if a variable or method is composed of more than one word
-(glued together of course) the second and following word(s) should begin with
-a capitalized letter. for example in the following code snippet:
-
-String name = "titi";
-Entity contentEntity = getContent();
-contentEntity.setPropertyForValue("name", name);
-
-some java code convention docs:
-
-http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html
diff --git a/doc/DC.txt b/doc/DC.txt
deleted file mode 100755 (executable)
index d251178..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-Dublin Core (http://purl.org/DC)
-----------------------------------------------------------------
-
-Bei der Dublin Core Metadata Initiative handelt es sich um ein 
-Projekt, dass einen "common core of semantics for resource 
-description" schafft. Selbstdarstellung unter 
-
-       http://purl.org/DC/about/index.htm
-
-
-Die Datenbankstruktur von Webdb/NA von der Bennenung soweit moeglich
-an das
-
- "Dublin Core Metadata Element Set, Version 1.1: Reference Description
-  Beschreibung unter http://purl.org/DC/documents/rec-dces-19990702.htm"
-
-angelehnt. Dublin Core Metadaten werden entsprechend untenstehendem Matching
-in die Header der produzierten Seiten geschrieben...
-
-
-Matching:
-
-Dublin Core umfasst 15 Attribute. Beschreibung der Attribute siehe oben.
-Angaben in eckigen Klammern beziehen sich auf Funktionalitaeten, die z.Z.
-noch nicht implementiert sind.
-
-Im folgenden, wie die DC-Attribute in den Tabellen repraesentiert sind:
-
-MEDIA/IMAGE Tabelle:
-
-1.     DC Element: Title  
-       MEDIA Element: title
-
-2.     DC Element: Creator
-       MEDIA Element: creator / to_creator
-
-3.     DC Element: Subject
-       MEDIA Element: keywords [/ keywords n:m]
-
-4.     DC Element: Description
-       MEDIA Element: desciption
-
-5.     DC Element: Publisher
-       MEDIA Element: to_publisher
-
-6.     DC Element: Contributor
-       MEDIA Element: to_publisher
-
-7.     DC Element: Date
-       MEDIA Element: publish_date
-
-8.     DC Element: Type
-       MEDIA Element: to_media_type.dcname
-
-9.     DC Element: Format
-       MEDIA Element: to_img_format.mimetype
-       [fuer video/audio dann analog]
-
-10.    Element: Identifier
-       MEDIA Element: publish_server + publish_path
-
-11.    DC Element: Source
-       MEDIA Element: source
-
-12.    DC Element: Language
-       MEDIA Element to_lang
-
-13.    DC Element: Relation
-       MEDIA Element: to_media_folder
-
-14.    DC Element: Coverage
-       MEDIA Element: place [ / to_place]
-
-15.    DC Element: Rights
-       MEDIA Element: to_rights
-
--------------------------------------------------------------------------
-
-
-CONTENT Tabelle:
-MEDIA/IMAGE Tabelle:
-
-1.     DC Element: Title  
-       MEDIA Element: title
-
-2.     DC Element: Creator
-       MEDIA Element: creator / to_creator
-
-3.     DC Element: Subject
-       MEDIA Element: keywords [/ keywords n:m]
-
-4.     DC Element: Description
-       MEDIA Element: desciption
-
-5.     DC Element: Publisher
-       MEDIA Element: to_publisher
-
-6.     DC Element: Contributor
-       MEDIA Element: to_publisher
-
-7.     DC Element: Date
-       MEDIA Element: publish_date
-
-8.     DC Element: Type
-       MEDIA Element: to_media_type.dcname
-
-9.     DC Element: Format
-       MEDIA Element: to_img_format.mimetype
-       [fuer video/audio dann analog]
-
-10.    Element: Identifier
-       MEDIA Element: publish_server + publish_path
-
-11.    DC Element: Source
-       MEDIA Element: source
-
-12.    DC Element: Language
-       MEDIA Element to_lang
-
-13.    DC Element: Relation
-       MEDIA Element: to_media_folder
-
-14.    DC Element: Coverage
-       MEDIA Element: place [ / to_place]
-
-15.    DC Element: Rights
-       MEDIA Element: to_rights
-
diff --git a/doc/INSTALL.mir b/doc/INSTALL.mir
deleted file mode 100755 (executable)
index a4411bb..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-MIR INSTALLATION HOWTO
-
-Last updated: $Date: 2003/12/03 18:10:45 $
-----------------------------------------------------------------
-
-Here is a short installation-howto of Mir.
-
-
-prerequisites: 
-
-- tomcat 4.0.4+ or 3.3 (4.0.3 and below have some bad bugs) 
-  tomcat is available from http://jakarta.apache.org/tomcat/
-- apache 1.3.x. with mod_jk.so. As far as I can tell the connector for 2.x is
-  still rather undocumented. http://httpd.apache.org
-- postgres 7.1+
-- ant (a java-based make) 
-- jaxp-1.1 (a SAX 2.0 compliant XML parser, comes with ant >= 1.4)
-- the JAI image framework (Java Advanced Imaging) version 1.1.2 . Get it from 
-  java.sun.com. You need both: JAI and JAI Image I/O. Install those two in
-  the JRE running tomcat.
-
-- A good reading of Tomcat, Apache and Postgresql documentation if you are not
-  familiar with any of them. The documentation is available at:
-  http://jakarta.apache.org/tomcat/tomcat-4.0-doc/index.html,
-  http://httpd.apache.org/docs/ and http://www.postgresql.org respectively.
-
-1. checkout the cvs
-
-CVS LOGIN:
-
-  cvs -d :pserver:anonymous@mir.indymedia.org:/var/lib/cvs login
-       password: anonymous
-
-CVS CHECKOUT:
-
-       cvs -d :pserver:anonymous@mir.indymedia.org:/var/lib/cvs co -r MIR_1_1 mir
-
-
-2. customize the config: 
-
-       cd mir/etc
-       cp config.properties-dist config.properties 
-
-now customize config.properties for your needs.
-
-
-3. configure the perms.sh file if neccessary -- IMPORTANT! READ THIS!
-We provide a script that sets all files' and direcories' permissions to
-a quite reasonable state. This script gets automagically called by
-ant after compilationl. The most important thing you have to do after
-compiling Mir is to ensure that the log files -- especially 
-dbentity.log -- are not readable by users that could compromise 
-system security, because all passwords and the like will be logged here.
-       
-       cp perms.sh-dist perms.sh
-
-Now, change the install directory and group in perms.sh
-
-       edit perms.sh 
-
-4. There is NO step 4!!
-
-5. compile. For this step, you have to make sure that the TOMCAT_HOME
-environment variable is set to the root of your tomcat installation.
-The build.xml compile target will give up if this is not set.
-
-Do this as root so the permissions script is able to set
-the permissions and owners correctly.
-
-    ant 
-
-
-6. Link in the webapps directory of tomcat to the install directory (the 
-directory is in mir/bin/mir (Here and in the rest of this document,
-we assume you called the link "Mir", but this could be named anything.)
-       cd ${TOMCAT_HOME}/webapps 
-       ln -s /path/to/mir/bin/mir Mir
-
-with tomcat 4.0.x, you could dynamically reload and stop the Mir webapp without
-restarting tomcat by using the "Manager App" with the following url:
-
-http://localhost:8080/manager/stop?path=/Mir
-
-This is practical if you are running several installations of mir on one 
-tomcat or other webapps and can't afford to shutdown all of them.
-See the tomcat documentation to learn how to enable and use the manager app.
-
-7. Follow the installation instructions of JAI / JAI Image I/O.
-
-8a. create a new database 
-The database name should be the same as in config.properties. Please look at
-the section "Database.*" to look up the names or change them to your needs. 
-
-It is wise in terms of system security to use an unprivileged user for this
-task instead of the superuser. This is because if Mir uses the superuser to
-connect to the database and anybody manages to find out the password Mir 
-uses to connect, the attacker can take over the complete database. So, in
-the following examples, we assume that the database name is "Mir", the
-database user will be "joe" and the password is "joshua". Please note that
-this particular password is far from being a good one. Watch "Wargames" for
-details. =B) 
-
-
-To access the database as the database superuser, you either have to log in
-as postgres on Unix level (which we don't recommend because you will need
-another user to have a login shell and a password which makes system
-penetration more likely) or you have to tell PostgreSQL with each
-application call that you want to connect as a specific user. In the 
-following example we'll create the mir database as postgreSQL user 
-"pete".
-
-       cd mir/dbscripts
-       su postgres
-       ./createmirdb.sh mir pete joe joshua
-
-8b. Apply neccessary changes to config.properties
-
-Please open config.properties and look for the lines that begin with
-"Database.". The interesting properties are "Username", "Password", "Host"
-and "Name". Change these properties so that they reflect the settings you
-used to create the database and the user.
-
-You should make sure that no copy of config.properties (neither in mir nor
-in Mir/src nor in Mir/WEB-INF/classes nor in the directory tree you compiled
-Mir from) is world-readable. Else you wouldn't have to install a password,
-anyway.
-
-8c. Setup PostgreSQL so that all localhost connections have to pass a 
-password
-
-In /etc/postgresql/pg_hba.conf, change the line with 127.0.0.1 as follows:
-
-host         all         127.0.0.1     255.0.0.0           password
-
-This means: All connections from 127.0.0.1 to any database will have to 
-authenticate themselves with a password. Please refer to the PostgreSQL
-documentation if you want a different authentication setup. Make sure
-however that mir can connect to it's database using password authentication.
-
-9. For now, there's no step 9 either.
-
-10. Tweak mime-type extensions mappings in etc/web.xml file.
-
-*** Note the defaults should be o.k for most installations ***
-
-Add or remove any mime types you wish to support. This is used to figure
-out the mime-type when (broken browsers?) browsers don't send the mime-type
-in the content-type header field when uploading a media file. Note add the
-moment you still have to add these to the media_type SQL table as well which
-maps the mime-types to the correct mediaHandler class. See the comments in
-the MirMedia class in javadoc for more details.
-
-11. restart tomcat 
-
-12. configure mod_jk 
-
-There are 2 ways to do this. auto-generation of mod_jk.conf or manula JKMount
-lines. (rumour has it that Tomcat 4.0.x doesn't support auto-generation, but
-this is unconfirmed).
-
-In both examples please note that the JkWorkersFile line only needs to appear
-once per Apache config.
-
-Also this assumes that your tomcat installation has it's ajp13 conenctor 
-turned on. See tomcat's server.xml file and documentation for this. Chances
-are that it is turned on.
-
-Method a). The automatic mod_jk.conf method:
-
-insert the following patch into /etc/apache/httpd.conf. Edit the directories
-to suit your needs.
-
-<IfModule mod_jk.c>
-JkWorkersFile /path/to/tomcat/conf/workers.properties
-Include /path/to/tomcat/conf/mod_jk.conf-auto
-</IfModule>
-
-Do not put any JkMount lines into your httpd.conf!
-
-If mod_jk.conf-auto doesn't get written or is 0 bytes in size, check your
-system for file ownership/permissions problems.
-
-Method b). Manual JKMount lines
-
-insert the following patch into /etc/apache/httpd.conf. Edit the directories
-to suit your needs.
-
-<IfModule mod_jk.c>
-JkWorkersFile /path/to/tomcat/conf/workers.properties
-JkMount /Mir ajp13
-JkMount /Mir/* ajp13
-</IfModule>
-
-
-13. configure apache for the static site
-
-* Make sure that if you are using a non standard character set enconding that 
-  Apache doesn't accidentally send the wrong encoding in the HTTP headers.
-edit http.conf:
-* set the document root to the same directory as in the mir config file
-* enable shtml includes:
-  - add LoadModule includes_module /usr/lib/apache/1.3/mod_include.so
-  - make sure your directory contains "Options Includes"
-* Determine if you need to modify any apache mime-mappings
-  - The web-server host must recognize the .m3u, .pls and other file extensions
-    and send the proper "audio/x-mpegurl" and "audio/x-scpls" mime-types
-    respectively.  If the web server is apache, it's easy, just
-    add:
-    
-    audio/x-mpegurl                 m3u
-    audio/x-scpl                    pls
-    
-    to the file pointed to by the "TypesConfig" command in your apache config
-    file. Or add and equivalent AddType command to your httpd.conf.  Of course
-    this assumes that the mod_mime is loaded.
-
-that's it :)
-
-now the admin-application is accesable via:  
-
-       http://host/Mir/servlet/Mir 
-
-and the openposting-servlet via  
-       
-       http://host/Mir/servlet/OpenMir
-
-standard login is admin/indymedia. See the webdb_users SQL table to change/add
-users or passwords.
-
-
-SEARCHING
-
-The Mir code offers no internal search facilities, rather, the design
-expects the use of an external program to crawl and index the static
-site.  One (recommended) tool for doing this is htdig
-(http://htdig.org), which generates static databases of the site
-content and then accesses those databases through a very fast CGI
-program written in C.  In the scripts directory, a perl CGI script 
-which wraps calls to htsearch is provided (scripts/search.pl) which
-will allow searching based off of media type.  (This is possible
-because the standard templates will include META keywords like
-hasAudio, hasVideo, etc.)  
-
-UPGRADING
-
-see the UPGRADING.mir file.
-
-TROUBLESHOOTING
-
-You can give these a try if anything goes wrong:
-
-+ Restart Tomcat. Especially after compiling the sources Tomcat has to be
-  restarted.
-
-+ Check file permissions and ownership. Try and run perms.sh.
-
-----------------------------------------------------------------
-
-$Date: 2003/12/03 18:10:45 $ - the Mir coders
diff --git a/doc/INTERNATIONALIZATION.howto b/doc/INTERNATIONALIZATION.howto
deleted file mode 100755 (executable)
index b6b2e47..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-MIR INTERNATIONALIZATION HOWTO
-----------------------------------------------------------------
-
-this short howto explains how to use the internationalization 
-features of mir and how you can translate mir to other 
-languages. this is actually very easy:
-
-
-* properties files (step 1)
-
-add a new file to the bundles/ directory. it should
-be called exactly like the other files there, except
-for the language code, which is the part after the underscore.
-at the moment these files are called 'admin_XX.properties', so
-
-admin_de.properties contains the strings for the german language
-admin_en.properties is the one for english.
-admin.properties is always used as a fallback and contains imc
-spcific information at the moment (this should probably change)
-
-the correct language code for your language can be found at
-http://www.w3.org/WAI/ER/IG/ert/iso639.htm, for example.
-
-
-* translation (step 2)
-
-the files just contain key and value pairs of the form 
-key=value. if a value contains something like {0}, {1}, and so
-on, this means, that these placeholders are replaced when the
-phrase is used. this is for example used for the key 
-show_from_to=showing from {0} to {1}. {0} and {1} get replaced 
-with the number of the first and the last record shown.
-
-in you new file (say admin_es.properties) you translate every key
-into the appropriate phrase in your language.
-
-
-* adding keys to templates
-
-you can define additional keys just by adding them to the 
-properties file and by referncing them in the freemaker template
-with ${lang("keyname")}. you should do that every time you need
-a language specific string!
-
-
-* renaming keys
-
-some keys might not have a perfectly fitting name at the moment.
-if you want to rename a key, please take care that you rename it
-in ALL properties files and ALL templates. take care.
-
-----------------------------------------------------------------
-27.3.2002, br1
diff --git a/doc/KNOWN_BUGS b/doc/KNOWN_BUGS
deleted file mode 100755 (executable)
index 32ef729..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-last changed: $Date: 2003/06/27 02:43:42 $ 2002 mir-coders
--------------------------------------------------------------------
-
-In all versions
-===============
-
-* the JAI library used for creating thumnails of images will often make the
-  thumbnail for a GIF or PNG image look like it has some television set snow in
-  it. The workaround would be to upload Jpeg images if you can. We are looking
-  into replacing JAI with another library.
-  Zapata: I fixed this (hopefully)
-
-* when deleting an item, be it an article or an uploaded media file, the action
-  will remove the data/meta-data from the DB and prevent it from show up in
-  lists, but it will not delete the file from the filesystem. hopefully this
-  will be fixed before 1.1.0 is released and in 1.0.1. (FIXME: is this still a
-  problem in the HEAD branch?)
-  Zapata: Deleting objects makes them untraceable and is thus generally a bad 
-  idea. It can be so configured (using producers.xml) that hidden stuff (articles, 
-  media) are deleted
-  
-* some obscure "under certain conditions" corner cases listed in our bug tracker
-  at https://prod.indymedia.nl/mantis
-* some others that I'm forgetting now.
diff --git a/doc/LOCALIZER.HOWTO b/doc/LOCALIZER.HOWTO
deleted file mode 100755 (executable)
index 5fd5170..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Version: $Date: 2003/11/24 19:57:54 $
-
-This is the HOWTO of the Localization infrastructure 
-which allows easy low-level customization of Mir.
-
-
-1. Mir.Localizer
-
-In the file config.properties-dist 
-Mir.Localizer=mircoders.localizer.basic.MirBasicLocalizer
-
-JUST NOTES:
-
--Document how to enable your own CVS tree
--Localizer code must be in etc/extrasource
--build.xml is aware of etc/extrasource
--contents of etc can be stored in extra cvs
--which of etc is known to ant?
--outside of etc nothing should be altered!
--producers can be configured in config.properties
diff --git a/doc/LONG.INSTALL.mir b/doc/LONG.INSTALL.mir
deleted file mode 100755 (executable)
index 7a0a0fc..0000000
+++ /dev/null
@@ -1,537 +0,0 @@
-MIR INSTALLATION HOWTO
-
-Last updated: $Date: 2003/01/18 08:44:09 $
-----------------------------------------------------------------
-
-Here is a short installation-howto of Mir, somewhat more explicit than
-the earlier version.  Some Debian-specific instructions are given.  
-
-
-prerequisites: 
-
-- tomcat 4.0.4 (4.0.3 and below have some bad bugs) or above (3.3 works too as
-  of 04.04.2002, but this could change)
-  tomcat is available from http://jakarta.apache.org/tomcat/
-- apache 1.3.x. with mod_jk.so. As far as I can tell the connector for 2.x is
-  still rather undocumented. http://httpd.apache.org
-- postgres 7.1.x or 7.2.x. http://www.postgresql.org
-- ant (a java-based make) 
-- jaxp-1.1 (a SAX 2.0 compliant XML parser, comes with ant >= 1.4)
-- the JAI image framework (Java Advanced Imaging) versin 1.1.1 . get it from 
-  java.sun.com. ** NOTE: because JAI uses a native acceration library (a .so)
-  it must be placed in tomcat's "lib" (i.e $TOMCAT_HOME/common/lib) directory and
-  not under the default webapps/Mir/WEB-INF/lib directory **
-- A good reading of Tomcat, Apache and Postgresql documentation if you are not
-  familiar with any of them. The documentation is available at:
-  http://jakarta.apache.org/tomcat/tomcat-4.0-doc/index.html,
-  http://httpd.apache.org/docs/ and http://www.postgresql.org respectively.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-0. To set all this up on Debian:
-
-make sure you have stable, testing, and unstable listings in
-/etc/apt/sources.list.  THen do all the following as root or using sudo!
-
-If you already have tomcat, and it's working well with apache, then
-skip directly to (c).  If it's not working well, then make sure you
-purge _all_ conf files & so forth ( though it never hurts to back them
-up first).  "apt-get remove --purge" may not get rid of everything; try 
-
-locate tomcat
-and then delete all the files you find (again, if you're unsure what
-they are, then back them up first).
-
-
-(a) Install Java 
-apt-get install j2sdk1.3 j2sdk1.3-doc
-
-JAVA_HOME=/usr/lib/j2sdk1.3; export JAVA_HOME
-PATH=$PATH:$JAVA_HOME/bin; export PATH
-(add these lines to your .bashrc as well)
-
-(b) Installing Tomcat and Apache
-
-As root, do the following:
-apt-get install apache 
- configure apache by editing httpd.conf:
-* enable shtml includes:
-  - add LoadModule includes_module /usr/lib/apache/1.3/mod_include.so
-  - make sure your directory contains "Options Includes"
-* Determine if you need to modify any apache mime-mappings
-  - The web-server host must recognize the .m3u, .pls and other file extensions
-    and send the proper "audio/x-mpegurl" and "audio/x-scpls" mime-types
-    respectively.  If the web server is apache, it's easy, just
-    add:
-    
-    audio/x-mpegurl                 m3u
-    audio/x-scpl                    pls
-    
-    to the file pointed to by the "TypesConfig" command in your apache config
-    file. Or add and equivalent AddType command to your httpd.conf.  Of course
-    this assumes that the mod_mime is loaded.
-* Make sure that if you are using a non standard character set enconding that 
-  Apache doesn't accidentally send the wrong encoding in the HTTP headers.
-
-
-
-Now deal with Tomcat:
-apt-get install -t unstable tomcat4 tomcat4-webapps tomcat4-admin 
-       --> this gets you tomcat4.1.  You can work with tomcat 4.0.4
-       as well, but a couple of specific configuration elements are
-       different.  To get 4.0.4, run the following:
-       apt-get install -t testing tomcat4 tomcat4-webapps
-apt-get install apachelib-java
-
-Tomcat will be installed in /usr/share/tomcat4, so you should put 
-
-CATALINA_HOME=/usr/share/tomcat4; export CATALINA_HOME
-TOMCAT_HOME=$CATALINA_HOME; export TOMCAT_HOME
-
-in your .bashrc; you might as well execute the ocmmand right now as
-well.  
-
-I found it somewhat difficult to get Tomcat and Apache working
-   together, until I emailed the Debian package maintainer, who told
-   me that he had purposely removed the mod_jk.conf-auto function from
-   Tomcat4.1!  This is because Debian encourages Tomcat users to
-   switch to mod_webapp instead.  You may want to try this option
-   out.  I didn't, because I was able to get it working using the
-   JkMount option.  So in /etc/apache/httpd.conf, look for a section
-   like this at the end:  
-       <IfModule mod_jk.c>                                                           
-       # The following line is for apacheconfig - DO NOT REMOVE!         
-       JkWorkersFile /etc/tomcat/jk/workers.properties                   
-       Include /var/lib/tomcat/conf/mod_jk.conf                          
-       </IfModule>                                                       
-                                                                       
-   This has been insrted by libapache-java to try to get mod_jk to
-   work. unfortunately it doesn't work with Tomcat 4.1, so replace it
-   with the following:
-
-       <IfModule mod_jk.c>                                               
-       # The following line is for apacheconfig - DO NOT REMOVE!         
-       JkWorkersFile /etc/tomcat/jk/workers.properties                   
-       JkMount /*.jsp ajp13                                              
-       JkMount /Mir ajp13                                                
-       JkMount /Mir/* ajp13                                              
-       JkMount /servlet ajp13                                            
-       jkMount /examples/* ajp13                                                 
-       #Include /var/lib/tomcat/conf/mod_jk.conf                         
-       </IfModule>                                                       
-restart tomcat(as root):
-/usr/share/tomcat4/bin/shutdown.sh
-/usr/share/tomcat4/bin/startup.sh
-restart apache(as root):
-apachectl restart
-
-In your browser, check to see if each pogram is working on its own:
-http://localhost should give you the debian apache start page
-http://localhost:8180 should give you the tomcat start page
-
-now check to see if mod_jk is allowing the two programs to connect:
-http://localhost/examples/servlets/index.html should give you the
-Tomcat example servlets.  
-
-Once this is working, you should enable the tomcat manager
-application:  
-cd /usr/share/tomcat4/conf
-open tomcat-users.xml in a text editor.  Add a line like this:
-
-<user username="name" password="password" roles="standard,manager,admin"/>
-
-You should now be able to click on the "Manager" link on the Tomcat
-home page, log in, and use the Manager functions.  This is extremely
-convenient when you're eloading Mir multiple times later on!
-
-(c) install postgres:
-apt-get install postgresql postgresql-client postgresql-doc
---> the new postgres package should work fine with Mir.  Make sure you
-enable UNICODE, and if asked about JDBC (you shouldn't be) make sure
-to enable it as well. if you would like to try a graphical frontend
-for the database, find one using
-
-apt-cache show postgresql
-
-fmailiarize yourself with the psql interface, and the function of the
-"postgres" user.
-
-(d) install JAI
-go to:
-http://java.sun.com/products/java-media/jai/downloads/download.html
-
-and download the "CLASSPATH for Linux" version of the JAI package
-(1.1.01 works fine, later versions have not been tested by me) to 
-/usr/share/tomcat4/common/lib
-
-now:
-
-cd /usr/share/tomcat4/common/lib
-
-gunzip "name_of_file.tar.gz" (don't use the quotes: replace with the
-real name of the file you downloaded!)
-
-tar -xvf "name_of_file.tar" 
-
-read the instructions in
-/usr/share/tomcat4/common/lib/jai_whatever_version_you_have/INSTALL-jai.txt
-
-Now add the JAI files to your CLASSPATH and LSD_LIBRARY_PATH:  
-JAIHOME=$TOMCAT_HOME/common/lib/jai-1_1_1_01/lib; export JAIHOME
-CLASSPATH=$JAIHOME/jai_core.jar:$JAIHOME/jai_codec.jar:$JAIHOME/mlibwrapper_jai.jar:$CLASSPATH;
-export CLASSPATH
-LD_LIBRARY_PATH=.:$JAIHOME:$CLASSPATH; export LD_LIBRARY_PATH
-
---> make sure to replace "jai-1_1_1_01" in the above with the
-version-number of your copy of JAI
---> as above, it's a good idea to add these lines to your .bashrc
-
----------------------------------------------------------------
-
-
-(1) CONFIGURE MIR!
-
-(a).  get the latest version:
-
-cd to the directory where you would like to install the mir package
-
-cd /absolute/path
-
-CVS LOGIN:
-
-  cvs -d :pserver:anonymous@mir.indymedia.org:/var/lib/cvs login
-       password: anonymous
-
-CVS CHECKOUT:
-
-       cvs -d :pserver:anonymous@mir.indymedia.org:/var/lib/cvs co mir 
-
-
-(b) customize the config: 
-
-       cd mir/etc
-       cp config.properties-dist config.properties 
-
-now customize config.properties for your needs.  config.properties is
-pretty well-documented, but read it carefully.  I had to recompile
-several times before I got all the pathnames right.
-
-(c) configure the perms.sh file if neccessary -- IMPORTANT! READ THIS!
-We provide a script that sets all files' and direcories' permissions to
-a quite reasonable state. This script gets automagically called by
-ant after compilationl. The most important thing you have to do after
-compiling Mir is to ensure that the log files -- especially 
-dbentity.log -- are not readable by users that could compromise 
-system security, because all passwords and the like will be logged here.
-       
-       cp perms.sh-dist perms.sh
-
-Now, change the install directory and group in perms.sh
-
-       edit perms.sh 
-
-
-(d) Customize the templates
-you need to edit the templates before compiling, or not all of your
-changes will show up in the produced site.  If this is too
-intimidating, don't worry -- you can always recompile!  It only takes
-about a minute...
-
-(e) check web.xml!
---> tomcat 4.1 has a different method of composing servlet URL's, so
-if you are uasing 4.1, you wil need to make some minor changes to
-mir/etc/web.xml
-
-look for sections like this: 
-  <servlet-mapping>
-        <servlet-name>
-            Mir
-        </servlet-name>
-        <url-pattern>
-            /Mir
-        </url-pattern>
-    </servlet-mapping>
-
-the url-pattern has to change; so replace the above with:
-  <servlet-mapping>
-        <servlet-name>
-            Mir
-        </servlet-name>
-        <url-pattern>
-            /servlet/Mir
-        </url-pattern>
-    </servlet-mapping>
-make sure to do the same for OpenMir and OutputMir.
-
-
--------------------------------------------------------------
--------------------------------------------------------------
-IMPORTANT!  It is a good idea to skip ahead to (2) and create the
-Postgres database at this point.  Then cd back to the mir directory,
-and continue.  
--------------------------------------------------------------
--------------------------------------------------------------
-
-(f) compile. Make sure all the environment variables are set as
-   indicated in section (0), or build.xml will not run properly:
-
-su
-ant
-
-  This should take about a minute.  If you don't get an error, run
-   perms.sh:
-       sudo perms.sh
-
-
-Do this as root so the permissions script is able to set
-the permissions and owners correctly.
-   
-
-(g) Get Tomcat to recognize Mir.
-Link in the webapps directory of tomcat to the install directory
-(unless you changed the setting in config.properties, the 
-directory is called "Mir" and is located in the same directory in which 
-you installed the "mir" directory). (Here and in the rest of this document,
-we assume you called the link "Mir", but this could be named anything.)
-       cd /path/to/tomcat/webapps (tomcat-4.0.x/webapps)
-       ln -s /path/to/Mir Mir
-
-dynamically reload Mir: 
-
-http://localhost:8180/manager/stop?path=/Mir
-if you're not using the Debian installation, you need to use:
-http://localhost:8080/manager/stop?path=/Mir
-
-if you're using Tomcat 3.3, you need to restart Tomcat (consult the
-docs for how to do that).  
-
-
-(h) Copy any dynamic library files ending with ".so" (so far only the JAI native
-acceleration library found in the JAI package tarball or zip from sun) to your
-$JAVA_HOME/jre/lib/i386 directory (where the other ".so" files live). Or, you
-can skip the whole thing and live without "native" acceleration for image
-manupulation.
-
-(2) CREATE AND CONLFIGURE THE MIR DATABASE!
-
-Review mir/etc/config.properties.  Look carefully at the entries you
-put in the DATABASE SETUP section, especially the Username, Password,
-Host, and Name variables.  If you don't know anything about Postgres,
-look over the INSTALL.postgresql document, which is very helpful (but
-remember, you don't need to install postgresql from scratch
-anymore if you're on Debian woody!).  Please do not use the "postgres"
-user in config.properties -- this is a serious security risk.  Choose
-a username,a password, and a database name, then put those values in
-config.properties if you haven't already.  
-
-(a) Create the new database
-
-We create and configure the database as posgresql user "postgres":
-
-   createdb -U postgres --encoding=unicode Mir 
---> here and elsewhere, replace "Mir" with the name you already chose
-for your database
-
-
-(b) create an unprivileged database user for Mir
-First, connect to the database as the database's superuser. 
-
-       psql -U postgres Mir
-
-Now we create the actual user. Please choose a password that is hard to 
-guess instead of "joshua". Good passwords have characters and numerals in
-it, have no link to its owner (like being her birthday, age, name of her 
-husband, dog, child, car, favourite beer brand). A good password looks like
-this: "8ncx4un".
-    
-    CREATE USER Mir WITH PASSWORD 'joshua' NOCREATEDB NOCREATEUSER;
---> again, don't just copy this into the psql command line -- replace
-"Mir" and "joshua" with your username and password from config.properties
-
-now exit: 
-\q
-
-
-(c) create base table
-cd back to the mir home directory.  now execute the following:
-
-       psql -Upostgres -f dbscripts/create_pg.sql Mir
-now quit psql:
-        \q
-back in the shell, execute the dbscripts:
-    for i in dbscripts/help*.sql ; do psql -Upostgres -f $i Mir ; done
-    for i in dbscripts/populate*.sql ; do psql -Upostgres -f $i Mir ; done
-
-(d) Grant the required permissions to the new user
-First, make your new user into the database administrator for the new
-database (instead of postgres):
-psql -U postgres Mir
-     select * from pg_database;
-     select * from pg_user;
-you'll see a display like this:
-   usename    | usesysid | usecreatedb | usetrace | usesuper | usecatupd |  passwd  | valuntil
---------------+----------+-------------+----------+----------+-----------+----------+----------
- postgres     |        1 | t           | t        | t        | t         | ******** |
- matt         |      100 | t           | f        | t        | t         | ******** |
- mir          |      101 | f           | f        | f        | f         | ******** |
-
-followed by
-
-  datname  | datdba | encoding | datistemplate | datallowconn | datlastsysoid | datvacuumxid | datfrozenxid | datpath
------------+--------+----------+---------------+--------------+---------------+--------------+--------------+---------
-
- template1 |      1 |        5 | t             | t            |         16554 |        11258 |   3221236731 |
-
- template0 |      1 |        5 | t             | f            |         16554 |           49 |           49 |
-
- Mir       |      1 |        5 | f             | t            |         16554 |        10805 |   3221236278 |
-note the "usesysid" column for your new user, and the datname for your
-new database.  now execute the following line, obviousjly using the
-variable you just noted:
-
-update pg_database set datdba=USESYSID_FROM_PG_USER where datname=DATABASENAME
-
-now exit psql: 
-\q
-
-save the following lines to a file called set.permissions:
-
-select 'grant all on '||relname||' to Mir;'
-from pg_class
-where relname not like 'pg%'
-order by relname;
-
--->be sure to replace "Mir" with your username!!!
-
-(e) Apply neccessary changes to config.properties
-
---> if you folowed the instructions above, you shouldn't have to do
-this, but doublecheck!
-Please open config.properties and look for the lines that begin with
-"Database.". The interesting properties are "Username", "Password", "Host"
-and "Name". Change these properties so that they reflect the settings you
-used to create the database and the user.
-
-You should make sure that no copy of config.properties (neither in mir nor
-in Mir/src nor in Mir/WEB-INF/classes nor in the directory tree you compiled
-Mir from) is world-readable. Else you wouldn't have to install a password,
-anyway.
-
-(f) Setup PostgreSQL so that all connections have to pass a password
-
-In /etc/postgresql/pg_hba.conf you should make sure that nobody can
-use the database without a password, by inserting these lines:
-
-local        all                                          password
-host         all         127.0.0.1     255.0.0.0           password
-host         all         0.0.0.0       0.0.0.0             reject
-
-make sure you comment out all other permissions lines in this file!
-
-This means: All local connections (i.e. psql without "-h hostname" option)
-have to authenticate themselves with a password. All connections from
-localhost (127.0.0.1) have to supply a password, too. All other connections
-are rejected. This line doen't have to be there if you have a properly
-configured firewall but even if you do have one, it adds to the security in
-case an attacker penetrates the firewall by some hack.
-
-If you can't access PostgreSQL after this for any reason, try and change
-"password" in /etc/postgresql/pg_hba.conf to "trust". This should disable
-any authentication method and make the database accessible again. Please use 
-this setting only temporarily because anybody who can access the PostgreSQL
-server could take over the database completely this way. After you fixed
-your password setting, switch the setting back to "password".
-You may want to change your PostgreSQL password from time to time to make
-database takeover harder. Rememer: Security is a process.
-
-----------------------------------------------------------------
-
-AT THIS POINT YOU SHOULD HAVE A WORKING INSTAATION OF MIR!  CHECK TO
-MAKE SURE -- DON'T BOTHER WITH THE REST TILL YOIU'VE MADE MIR WORK ONCE!
-
-
-Goodies:
-
-(3) Add the dupe prevention trigger to the database:
-       cd mir/dbscripts/dupetrigger
-       
-       There, read INSTALL and follow the instructions.
-       
-
-(4) Tweak mime-type extensions mappings in etc/web.xml file.
-
-*** Note the defaults should be o.k for most installations ***
-
-Add or remove any mime types you wish to support. This is used to figure
-out the mime-type when (broken browsers?) browsers don't send the mime-type
-in the content-type header field when uploading a media file. Note add the
-moment you still have to add these to the media_type SQL table as well which
-maps the mime-types to the correct mediaHandler class. See the comments in
-the MirMedia class in javadoc for more details.
-
-11. restart tomcat 
-
-13. configure apache
-
-edit http.conf:
-* set the document root to the same directory as in the mir config file
-* enable shtml includes:
-  - add LoadModule includes_module /usr/lib/apache/1.3/mod_include.so
-  - make sure your directory contains "Options Includes"
-* Determine if you need to modify any apache mime-mappings
-  - The web-server host must recognize the .m3u, .pls and other file extensions
-    and send the proper "audio/x-mpegurl" and "audio/x-scpls" mime-types
-    respectively.  If the web server is apache, it's easy, just
-    add:
-    
-    audio/x-mpegurl                 m3u
-    audio/x-scpl                    pls
-    
-    to the file pointed to by the "TypesConfig" command in your apache config
-    file. Or add and equivalent AddType command to your httpd.conf.  Of course
-    this assumes that the mod_mime is loaded.
-
-that's it :)
-
-now the admin-application is accesable via:  
-
-       http://host/Mir/servlet/Mir 
-
-and the openposting-servlet via  
-       
-       http://host/Mir/servlet/OpenMir
-
-standard login is admin/indymedia. See the webdb_users SQL table to change/add
-users or passwords.
-
-
-SEARCHING
-
-The Mir code offers no internal search facilities, rather, the design
-expects the use of an external program to crawl and index the static
-site.  One (recommended) tool for doing this is htdig
-(http://htdig.org), which generates static databases of the site
-content and then accesses those databases through a very fast CGI
-program written in C.  In the scripts directory, a perl CGI script 
-which wraps calls to htsearch is provided (scripts/search.pl) which
-will allow searching based off of media type.  (This is possible
-because the standard templates will include META keywords like
-hasAudio, hasVideo, etc.)  
-
-UPGRADING
-
-see the UPGRADING.mir file.
-
-TROUBLESHOOTING
-
-You can give these a try if anything goes wrong:
-
-+ Restart Tomcat. Especially after compiling the sources Tomcat has to be
-  restarted.
-
-+ Check file permissions and ownership. Try and run perms.sh.
-
-----------------------------------------------------------------
-
-$Date: 2003/01/18 08:44:09 $ - the Mir coders
diff --git a/doc/README b/doc/README
deleted file mode 100755 (executable)
index 6ad2fb0..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-last changed $Date: 2003/11/24 19:57:54 $
------------------------------------------
-
-GENERAL INFO
-============
-
-Mir is an Open-Source java servlet based content managment system, designed to
-run an indymedia(type) website. Besides powering several indymedia sites, a
-number of progessive organizations use Mir customized for their own needs. Mir
-aims to provide sophisticated functionality, for example, complete
-multi-lingual content production, editing, administration, and presentation,
-while retaining the ability to be run on less than top of the line hardware
-through extensive static caching.
-
-Mir uses technologies such as Apache Tomcat and the Freemarker template engine.
-
-more info at: http://mir.indymedia.org
-
-development and general questions/discussion happens on the mir-coders mailing
-list: mir-coders at lists.indymedia.org
-
-for archives or to subscribe:
-
-http://lists.indymedia.org/mailman/listinfo/mir-coders
-
-mailing list for cvs commits:
-
-http://lists.indymedia.org/mailman/listinfo/Mir-cvs
-
-LICENSING
-=========
-
-Mir is licensed under the GNU GPL.
-
-FEATURES
-========
-
-* Static publishing: Mir produces static HTML files for easy mirroring and so
-  that the site can be viewed without creating a high load on servers. No fancy
-  caching mechanisms are necessary. The presentation and production are
-  completely independent from each other.
-* Very configurable (see the config.properties file)
-* Written in Java using standard servlet API and popular tools like those from
-  the Apache Jakarta project (http://jakarta.apache.org)
-* Uses the Freemarker template engine to allow easy modification of
-  site design without programming knowledge.
-* Structured Object oriented 4 layer design. Servlet modules, Entity/Database
-  (the persistance layer), Media handlers (an abstraction layer for
-  manipulating different media formats) and the Producer layer (for creating
-  the static html pages). see doc/CODESTRUCTURE for more details.
-* The persistance layer uses the poolman package for caching Database
-  connections. 
-* Entity object caching is integrated into the persistance layer.
-* Meta-data/Database schema and classification based on the Dublic Core
-  standard. Media folders, topics, features.
-* supports displaying the dynamic part of the site in multiple languages using
-  the Java Locale/language bundle standard (.properties files). Bundles exist
-  for spanish, english, dutch, quechua, turkish, german and aymara. The
-  upcoming 1.1  version (in CVS) supports producing the static site in several
-  languages.
-* Media abstraction layer to cleanly and easily handle/add different Media
-  formats like mp3, realmedia, video, etc.. uses mime-types to map to the
-  correct handler
-* Supports categorization into topics and media folders (eg. different folders
-  for different events), features, breaking news, newswire, etc..
-* Production of xml RDF syndication. e.g for the indymedia global newswire.
-* Powerful and rich admin/editor interface with features like the ability to
-  change the event date of an article, multiple ways to search.. help and much
-  more.
-* Ability to edit some static site files such as CSS, html include files
-  through a basic web based text editor.
-* Filtering of uploaded articles to remove unwanted HTML tags.
-* Can output articles into PDF (upcoming 1.1 version has better text wrapping
-  support).
-* Search via HTdig index of static files.  (upcoming 1.1 CVS version uses
-  integrated Jakarta Lucene for indexing the static files.)
-* Automatic thumbnail generation using Java Advanced Imaging (JAI). (1.1 will
-  probably use Jmagick)
-
-In the upcoming 1.1 release
-===========================
-
-* completely rewrite of the producer layer. Runs in it's own thread.
-  Configurable via an XML file to dynamically choose the structure the site
-  should take, what should be archived...
-* Introduction of the Localization infrastructure to allow easy low-level
-  customization of Mir.
-
diff --git a/doc/README.jikes b/doc/README.jikes
deleted file mode 100755 (executable)
index c8523d4..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-Last update: $Date: 2002/12/28 03:39:17 $
-
-As of this writing the IBM Jikes compiler up to and including version 1.15 does
-not work with mir. Jikes version 1.18 does work. We have not yet tested Jikes
-V1.16 and V1.17. It is possible that they may work.
diff --git a/doc/TODO.txt b/doc/TODO.txt
deleted file mode 100755 (executable)
index bd2d4f9..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-[Updated $Date: 2002/12/23 05:38:50 $]
-
-v 1.1
-
-* producers merged (done, max, mh)
-* bundle cleanup (done, br1)
-* new templates with css (done, thomas - max)
-* seperation of things that should be edited and things that dont change:
-    admin templates in templates, producer templates in templates-dist? 
-    (done, br1)
-* utf8 encoding (mh)
-* media refactoring (mh)
-* index.en.html ,etc..
-* more formats for media uploads --> generic media upload support (mh)
-* drop media_type table (mh)
-* yet another search format what to do about it..
-* merge StringUtil/util *Routines stuff into one
-* see for languages default --> merge it into OpenMir
-* Throwable Vs. Exception
-* merge MirConfig and config stuff in MirGlobal into one..
-* tuneup fileeditor
-* producer queue job stop/start
-* error reporting for Job queue?
-* set config paramater for default timezone.. (for use in templates)
-
-before 2.0
-
-* logging: log4j (max) --> is this not already a 1.1 item?
-* configuration (mh, max)
-* searching (john) --> is this not already a 1.1 item?
-* HTML validation, struts (br1)
-* PDF generation (john)
-* better user interface (br1)
-* split OpenPosting servlet modules or filter mechanism
-
-
-v 2.0
-
-* persistence layer: OJB or Torque (mh, idfx,...)
-* data model
-* struts (br1)
-* users / roles (max)
-* article translation
-
-
-general
-
-* mir website maintainance
-* website design / mir default templates
-* documentation
-
-
---- misc ---
-
-c) Coverage: Alternative start-page for e.g. a event like genua. every article that has
-something to do with this event can be seen on this page. (nn)
-b) P2P-Data-Transfer/Content-Syndication: Implementing RDF/RSS-Support or a own
-indymedia-protocoll.
-drop media_type table
-d) email-article-to-a-friend-servlet
-e) semidynamic create-pdf-from-article-servlet: every requested pdf should be cached (underway, john)
-f) servletapi-2.3: Filters for file upload (also in cos.jar)
-g) servletapi-2.3: use web.xml for simpler/better error handling.
-h) servletapi-2.3: set character encoding properly based on what the template says
-i) servletapi-2.3: servletapi-2.3 requires tomcat-4.x, so require it
-k) better transaction support in the DB/Persistance layer for more efficient
-use of DB.
-m) Editing producer-templates in the mir-servlet. (idfx)
-n) Media infrastructure stuff:
-  - make a sort of Factory to get handler perhaps in EntiyMediaType
-  - MediaHandler should take care of storage tablename, the entry in SQL is
-    redundant. -> get rid of it
-  - maybe get rid of the MediaTypeTable entirely and have it in a config file?
-  - use FM's TemplateMethodModel to access the MediaHandler method in templates
-    instead of the crude way it's done now.
-
-*) move log to WEB-INF!!! (security problem)
-*)
-
---- wishlist ---
-
-* search engine: foto small thumbnails
-* comments: mark last read comments
-* comments: allow some HTML (let user choose)
-* allow HTML in abstracts
-* preview for video
-* protection against spam
-       possibility to block submissions in case of spam attacks
-       apache: 1-2 postings / IP / minute
-       close artice for comments
-       image with password
diff --git a/doc/UPGRADING.mir b/doc/UPGRADING.mir
deleted file mode 100755 (executable)
index 9dc325e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-MIR UPGRADING HOWTO
-----------------------------------------------------------------
-
-For releases after 1.0.0-rc1, always check the NEWS file at the root of the
-tree to check the [Notes] section to see what you might have to adjust.
-
-For non releases or releases before 1.0.0-rc1, aka. the latest sources from
-CVS, it is a good idea to follow the advice below.
-
-Due to weaknesses of the current Mir configuration system, many folks get
-bitten after doing an update of their cvs tree. Suddenly Mir starts throwing
-weird exceptions, etc.. The cause is usually a new config option in the
-source/config.properties-dist that is missing from your
-source/config.properties file (the one that is actually used).
-
-a good way to check for this is to do the following (in the mir/ directory):
-
-cd source
-diff -u config.properties config.properties-dist
-
-for this unfamiliar with the diff(1) program, you'll see a bunch of lines, some
-starting with a "+" or "-". Look for a bunch of consecutive "+" symbols not
-immeadiately followed by a "-". that usually is a new config option that you
-should copy/paste (without the "+"'s of course) over to your existing
-config.properties file and modify if necessary.
-
-----------------------------------------------------------------
-
-last changed: $Date: 2002/12/07 07:00:16 $ - the Mir coders
index c2b7956..97949ae 100755 (executable)
@@ -1 +1,38 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r<html>\r<head>\r  <title></title>\r</head>\r<body>\r<h1>mir developer mission statement </h1>\r<br>\rbuild creative free software that allows people to share and access content\rin an accesible way that promotes participation and is insensitive to repression,\rfocussing to the needs of progressive grassroots organization.<br>\r<br>\r<h2>mir key features:</h2>\r<ul>\r  <li>cms(content management system) implemented in the java programming\rlanguage with an emphasis on design and structure.</li>\r  <li>simplicity of mirroring content.</li>\r  <li>production system&nbsp; of the cms is independent of publication system\rlocation and type</li>\r  <li>support for multiple languages, media types and publication means</li>\r  <li>implements a wide range of content submission, approval and publication\rmodels without the need to alter the underlying code, from complete open\rposting to total editorial control</li>\r</ul>\r</body>\r</html>
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <title>Mir mission statement</title>
+  </head>
+
+  <body>
+    <h1>mir developer mission statement </h1>
+
+    <p>
+      build creative free software that allows people to 
+      share and access content in an accesible way that 
+      promotes participation and is insensitive to 
+      repression, focussing to the needs of progressive 
+      grassroots organization.
+    </p>
+
+    <h2>mir key features:</h2>
+    <ul>
+      <li>cms(content management system) implemented in the 
+      java programming language with an emphasis on design 
+      and structure.</li>
+
+      <li>simplicity of mirroring content.</li>
+
+      <li>production system&nbsp; of the cms is independent 
+      of publication system location and type</li>
+
+      <li>support for multiple languages, media types and 
+      publication means</li>
+
+      <li>implements a wide range of content submission, 
+      approval and publication models without the need to 
+      alter the underlying code, from complete open posting 
+      to total editorial control</li>
+    </ul>
+  </body>
+</html>
\ No newline at end of file
index a8b6045..7395e48 100755 (executable)
@@ -1,2 +1,3 @@
 # put your own local admin properties in this file
 # (like for custom article types)
+
index 2937f00..97ed4a0 100755 (executable)
@@ -6,6 +6,8 @@ langcode=en
 optional=optional
 required=required
 
+general.unexpectederror=An unexpected error has occurred
+
 posting.htmltitle=Mir | open posting
 
 posting.step00= Step 00
@@ -44,11 +46,13 @@ posting.phone=your telephone number
 posting.language=the language of your article
 posting.text=your <b>article</b>
 posting.text.info=fill in the text of your article here
+posting.media.ftpmedia = FTP uploads (please enter the filename)
 posting.media=media
 posting.media.info=upload media-files (supported are jpg|gif|mp3|avi|qt|mpeg) max size: 20 Mb
 posting.media.howto=(Press "Browse" and select the file you want to upload)
 posting.media.media=Media
 posting.media.title=media sub-title
+posting.media.cancel=Cancel
 posting.submit.info=Please press submit <b>only once</b>!<br>It will appear in a few minutes on the main page. It might even take longer in case of technical problems.
 posting.criteria=
 posting.submit=Submit (patience is a virtue!)
@@ -56,7 +60,7 @@ posting.reset=Form Reset
 posting.error.missingpassword=The one-time password must be copied into the password field
 posting.error.invalidpassword=The one-time password was not copied correctly into the password field
 posting.error.missingfield=At least one field was not correctly entered
-media.error.unsupportedformat=The format of the media you uploaded is not supported
+media.error.unsupportedformat=The format of the media you uploaded ({0}) is not supported
 
 postingdone.htmltitle=open posting
 postingdone.title=You have successfully submitted your article
index 0b16d91..a3a1970 100755 (executable)
 # d) database config
 #
 # edit this to suit your needs
-# After you edited this file, "ant" has to be invoked.
-# To be sure, also restart Tomcat.
+# After editing this file, two steps need to be taken to make the changes effective:
+#   1. ant has to be invoked.
+#   2. tomcat needs to be restarted.
 #
-# Note that for Mir to work, Tomcat has to be set up to handle all
-# URLs that begin with /servlet. All other URLs are handled by Apache.
+# This file only contains the properties that are most often changed. To view all
+# possible config values, refer to the file default.properties, located in the
+# source directory. Don't change settings in default.properties however, instead
+# use this file.
 #
-# There are more configuration values located in the default.properties file
-# located in source/. If necessary these values can be overridden in this file.
+# Note: for filename values, by default, files are used relative to the servlet's
+# WEB-INF directory.
 #
 # The setup uses the following assumptions:
-# The URL to reach the site is http://mir.code-fu.org
+# The URL to reach the site is http://mir.someserver.org
 # The StorageRoot of this URL is /var/www/project/site/
 # All produced pages and media are located below this directory.
-# The servlets are also found there in a /servlet subdir.
-
 
 ################################################
 ############    A) GENERAL SETUP  ##############
@@ -53,14 +54,6 @@ Mir.Tech-email.name=mir-admins mailinglist
 Mir.Public-email.address=project@somemailserver.org
 Mir.Public-email.name=project mailinglist
 
-
-# DirectOpenposting
-# yes = articles appear in the newswire on the startpage directly after posting them
-# no  = new articles not in newswire by default
-#       and editors have to promote them before they show on startpage
-#
-DirectOpenposting=yes
-
 # Default timezone to display times in in admin, producers
 # use CET for Central European Time (Paris, Amsterdam)
 # more timezones here: http://www.postgresql.org/docs/7.2/static/timezones.html
@@ -68,46 +61,14 @@ DirectOpenposting=yes
 Mir.DefaultTimezone= UTC
 
 # Default date/time format
-#
+# For the syntax of the format, refer to
+# http://java.sun.com/j2se/1.3/docs/api/java/text/SimpleDateFormat.html
 Mir.DefaultDateTimeFormat = yyyy-MM-dd HH:mm
 
-# where to put the lucene index
-# for the build in searchengine
-# (must be created by you and writable by tomcat-user)
-#
-IndexPath=/var/www/project/lucineindex
-
-# temp-dir used for media-uploads
-#
-TempDir=/tmp
-
-# Logging
-# by default logs are found in bin/mir/WEB-INF/log
-#
-Log.LogClass = mir.log.log4j.LoggerImpl
-Log.log4j.ConfigurationFile = etc/log4j.properties
-Log.Home = log
-
-# Mir.Localizer
-# for your additional site-specific java-code
-#
-Mir.Localizer=mircoders.localizer.basic.MirBasicLocalizer
-
-# The location of the producer specifiations
-#
-Mir.Localizer.ProducerConfigFile=etc/producer/producers.xml
-
 # For missing values, the FallbackLanguage is used as default
 #
 Mir.Admin.FallbackLanguage=en
 
-# the templates
-#
-Mir.Localizer.Producer.GeneratorLibrary= default=freemarker(etc/producer/)
-Mir.Localizer.Admin.GeneratorLibrary= default=freemarker(templates/admin/)
-Mir.Localizer.OpenPosting.GeneratorLibrary= default=freemarker(etc/open/)
-
-
 #################################
 # admin interface configuration #
 #################################
@@ -123,36 +84,11 @@ Mir.Login.Languages=en;de;fr;nl;es;pt;eu;sv;tr;zh;gz
 #
 Mir.Admin.ShowLoggedinUsers=1
 
-# How should the custom operations (hide etc) in article and comment lists
-# be presented?
-# 0 = links, 1 = checkboxes, 2 = a listbox
-#
-Mir.Localizer.Admin.ListOperationsFlavor=1
-
-# How should the topics be presented on the article edit page?
-# 0 = in a multiselect list box, 1 = checkboxes
-#
-Mir.Localizer.Admin.TopicListFlavor=1
-
-# For the checkboxes flavour, how many columns should there be?
-#
-Mir.Localizer.Admin.TopicListColumns=3
-
-# In which order should the topic appear?
-#
-Mir.Localizer.Admin.TopicListOrder=title
-
 # enable deletion of comments/articles?
 #
 Mir.Localizer.Admin.AllowDeleteComment=1
 Mir.Localizer.Admin.AllowDeleteArticle=1
 
-# Article Preview Link URL (Link to produced articles from within admin)
-#
-Article.PublicUrl=http://mir.code-foo.org/en/${to_content.date.formatted.yyyy}/${to_content.date.formatted.MM}/${to_content.id}.shtml
-Comment.PublicUrl=http://mir.code-foo.org/en/${date.formatted.yyyy}/${date.formatted.MM}/${id}.shtml
-
-
 #######################
 # automated producers #
 #######################
@@ -196,9 +132,6 @@ Rsync.Script.Path=/var/www/bin/rsync-copy.sh
 ServletModule.FileEdit.Configuration= \
   includes:/var/www/project/site/includes:.*\\.inc:1
 
-
-
-
 ################################################
 ###########  B) STATIC SITE CONFIG #############
 ################################################
@@ -206,13 +139,13 @@ ServletModule.FileEdit.Configuration= \
 # the url of the static site
 # on the machine where mir runs on
 #
-Producer.ProductionHost=http://mir.code-fu.org
+Producer.ProductionHost=http://mir.someserver.org
 
 # the url of the public site
 # only different from ProductionHost if pages are copied to
 # one ore more mirror-servers for delivery
 #
-Producer.PublicationHost=http://mir.code-fu.org
+Producer.PublicationHost=http://mir.someserver.org
 
 # Produrce.StorageRoot is the directory, in which
 # the generated HTML pages will be stored
@@ -236,19 +169,19 @@ Producer.DocRoot=
 
 # the url of the video-server
 #
-Producer.Video.Host=http://mir.code-fu.org/video
+Producer.Video.Host=http://mir.someserver.org/video
 
 # the url of the audio-server
 #
-Producer.Audio.Host=http://mir.code-fu.org/audio
+Producer.Audio.Host=http://mir.someserver.org/audio
 
 # the url of the image-server
 #
-Producer.Image.Host=http://mir.code-fu.org/images
+Producer.Image.Host=http://mir.someserver.org/images
 
 # the url of the media-server
 #
-Producer.Media.Host=http://mir.code-fu.org/media
+Producer.Media.Host=http://mir.someserver.org/media
 
 # the url of the real-media-server
 #
@@ -328,7 +261,7 @@ Producer.ActionServlet=/servlet/Mir
 
 # the url of the openposting-servlet
 #
-Producer.OpenAction=http://mir.code-fu.org/servlet/OpenMir
+Producer.OpenAction=http://mir.someserver.org/servlet/OpenMir
 
 # the maximum allowed size of an uploaded media file in KB.
 #
@@ -343,7 +276,6 @@ ServletModule.OpenIndy.MaxMediaUploadItems=20
 ServletModule.OpenIndy.DefaultMediaUploadItems=1
 
 
-
 ######################
 # PDF configurations #
 ######################
@@ -370,17 +302,6 @@ PDF.Footer=Mir-CMS PDF-Newsletter.  Content is good, and free to use for non-com
 #
 PDF.PageSize=A4
 
-
-#the style sheet used to turn html into xsl:fo
-#this is not currently in use, so don't worry about it
-Producer.HTML2FOStyleSheet=/some/dir/mir/etc/producer/html2fo.xsl
-
-
-
-######################################################################
-#  edit with caution below this line
-######################################################################
-
 ################################################
 ############ D) DATABASE CONFIG   ##############
 ################################################
@@ -393,29 +314,16 @@ Database.Password=
 
 Database.Host=localhost
 Database.Port=5432
-
-Database.poolMin=1
-Database.poolMax=10
-Database.poolResetTime=1.0
-Database.PoolLog=log/pool.log
-Database.Limit=20
 Database.Driver=org.postgresql.Driver
 
 
-
 ############################################
-# servlet / module encoding configurations #
+# encoding configuration                   #
 ############################################
 
-# don't change this unless you really know your i18n.
 # The default encoding charset used in the written html files as well
 # as the dynamic output html.
-# also used for the HTML charset meta tag.
-#
-Mir.DefaultEncoding=UTF8
-
-# this encoding is used for the HTML charset meta tag.
-# it must be the html charset equivalent of the Java encoding above
-# don't change this unless...
-#
 Mir.DefaultHTMLCharset=UTF-8
+
+# The java equivalent of Mir.DefaultHTMLCharset
+Mir.DefaultEncoding=UTF8
diff --git a/etc/content-types.properties b/etc/content-types.properties
deleted file mode 100755 (executable)
index e3c4407..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-#sun.net.www MIME content-types table; version 1.6, 05/04/99
-#
-# Property fields:
-#
-#   <description> ::= 'description' '=' <descriptive string>
-#    <extensions> ::= 'file_extensions' '=' <comma-delimited list, include '.'>
-#         <image> ::= 'icon' '=' <filename of icon image>
-#        <action> ::= 'browser' | 'application' | 'save' | 'unknown'
-#   <application> ::= 'application' '=' <command line template>
-#
-
-#
-# The "we don't know anything about this data" type(s).
-# Used internally to mark unrecognized types.
-#
-content/unknown: description=Unknown Content
-unknown/unknown: description=Unknown Data Type
-
-#
-# The template we should use for temporary files when launching an application
-# to view a document of given type.
-#
-temp.file.template: /tmp/%s
-
-#
-# The "real" types.
-#
-application/octet-stream: \
-       description=Generic Binary Stream;\
-       file_extensions=.saveme,.dump,.hqx,.arc,.o,.a,.bin,.exe,.z,.gz
-
-application/oda: \
-       description=ODA Document;\
-       file_extensions=.oda
-
-application/pdf: \
-       description=Adobe PDF Format;\
-       file_extensions=.pdf
-
-application/postscript: \
-       description=Postscript File;\
-       file_extensions=.eps,.ai,.ps;\
-       icon=ps;\
-       action=application;\
-       application=imagetool %s
-
-application/x-dvi: \
-       description=TeX DVI File;\
-       file_extensions=.dvi;\
-       action=application;\
-       application=xdvi %s
-
-application/x-hdf: \
-       description=Hierarchical Data Format;\
-       file_extensions=.hdf;\
-       action=save
-
-application/x-latex: \
-       description=LaTeX Source;\
-       file_extensions=.latex
-
-application/x-netcdf: \
-       description=Unidata netCDF Data Format;\
-       file_extensions=.nc,.cdf;\
-       action=save
-
-application/x-tex: \
-       description=TeX Source;\
-       file_extensions=.tex
-
-application/x-texinfo: \
-       description=Gnu Texinfo;\
-       file_extensions=.texinfo,.texi
-
-application/x-troff: \
-       description=Troff Source;\
-       file_extensions=.t,.tr,.roff;\
-       action=application;\
-       application=xterm -title troff -e sh -c \"nroff %s | col | more -w\"
-
-application/x-troff-man: \
-       description=Troff Manpage Source;\
-       file_extensions=.man;\
-       action=application;\
-       application=xterm -title troff -e sh -c \"nroff -man %s | col | more -w\"
-
-application/x-troff-me: \
-       description=Troff ME Macros;\
-       file_extensions=.me;\
-       action=application;\
-       application=xterm -title troff -e sh -c \"nroff -me %s | col | more -w\"
-
-application/x-troff-ms: \
-       description=Troff MS Macros;\
-       file_extensions=.ms;\
-       action=application;\
-       application=xterm -title troff -e sh -c \"nroff -ms %s | col | more -w\"
-
-application/x-wais-source: \
-       description=Wais Source;\
-       file_extensions=.src,.wsrc
-
-application/zip: \
-       description=Zip File;\
-       file_extensions=.zip;\
-       icon=zip;\
-       action=save
-
-application/x-bcpio: \
-       description=Old Binary CPIO Archive;\
-       file_extensions=.bcpio; action=save
-
-application/x-cpio: \
-       description=Unix CPIO Archive;\
-       file_extensions=.cpio; action=save
-
-application/x-gtar: \
-       description=Gnu Tar Archive;\
-       file_extensions=.gtar;\
-       icon=tar;\
-       action=save
-
-application/x-shar: \
-       description=Shell Archive;\
-       file_extensions=.sh,.shar;\
-       action=save
-
-application/x-sv4cpio: \
-       description=SVR4 CPIO Archive;\
-       file_extensions=.sv4cpio; action=save
-
-application/x-sv4crc: \
-       description=SVR4 CPIO with CRC;\
-       file_extensions=.sv4crc; action=save
-
-application/x-tar: \
-       description=Tar Archive;\
-       file_extensions=.tar;\
-       icon=tar;\
-       action=save
-
-application/x-ustar: \
-       description=US Tar Archive;\
-       file_extensions=.ustar;\
-       action=save
-
-audio/basic: \
-       description=Basic Audio;\
-       file_extensions=.snd,.au;\
-       icon=audio;\
-       action=application;\
-       application=audiotool %s
-
-audio/x-aiff: \
-       description=Audio Interchange Format File;\
-       file_extensions=.aifc,.aif,.aiff;\
-       icon=aiff
-
-audio/x-wav: \
-       description=Wav Audio;\
-       file_extensions=.wav;\
-       icon=wav
-
-image/gif: \
-       description=GIF Image;\
-       file_extensions=.gif;\
-       icon=gif;\
-       action=browser
-
-image/ief: \
-       description=Image Exchange Format;\
-       file_extensions=.ief
-
-image/jpeg: \
-       description=JPEG Image;\
-       file_extensions=.jfif,.jfif-tbnl,.jpe,.jpg,.jpeg;\
-       icon=jpeg;\
-       action=browser;\
-       application=imagetool %s
-
-image/tiff: \
-       description=TIFF Image;\
-       file_extensions=.tif,.tiff;\
-       icon=tiff
-
-image/vnd.fpx: \
-       description=FlashPix Image;\
-       file_extensions=.fpx,.fpix
-
-image/x-cmu-rast: \
-       description=CMU Raster Image;\
-       file_extensions=.ras
-
-image/x-portable-anymap: \
-       description=PBM Anymap Format;\
-       file_extensions=.pnm
-
-image/x-portable-bitmap: \
-       description=PBM Bitmap Format;\
-       file_extensions=.pbm
-
-image/x-portable-graymap: \
-       description=PBM Graymap Format;\
-       file_extensions=.pgm
-
-image/x-portable-pixmap: \
-       description=PBM Pixmap Format;\
-       file_extensions=.ppm
-
-image/x-rgb: \
-       description=RGB Image;\
-       file_extensions=.rgb
-
-image/x-xbitmap: \
-       description=X Bitmap Image;\
-       file_extensions=.xbm,.xpm
-
-image/x-xwindowdump: \
-       description=X Window Dump Image;\
-       file_extensions=.xwd
-
-image/png: \
-       description=PNG Image;\
-       file_extensions=.png;\
-       icon=png;\
-       action=browser
-
-text/html: \
-       description=HTML Document;\
-       file_extensions=.htm,.html;\
-       icon=html
-
-text/plain: \
-       description=Plain Text;\
-       file_extensions=.text,.c,.cc,.c++,.h,.pl,.txt,.java,.el;\
-       icon=text;\
-       action=browser
-
-text/tab-separated-values: \
-       description=Tab Separated Values Text;\
-       file_extensions=.tsv
-
-text/x-setext: \
-       description=Structure Enhanced Text;\
-       file_extensions=.etx
-
-video/mpeg: \
-       description=MPEG Video Clip;\
-       file_extensions=.mpg,.mpe,.mpeg;\
-       icon=mpeg;\
-       action=application;\
-       application=mpeg_play %s
-
-video/quicktime: \
-       description=QuickTime Video Clip;\
-       file_extensions=.mov,.qt
-
-application/x-troff-msvideo: \
-       description=AVI Video;\
-       file_extensions=.avi;\
-       icon=avi
-
-video/x-sgi-movie: \
-       description=SGI Movie;\
-       file_extensions=.movie,.mv
-
-message/rfc822: \
-       description=Internet Email Message;\
-       file_extensions=.mime
-
-application/xml: \
-       description=XML document;\
-       file_extensions=.xml
-
-audio/mp3: \
-       description=MPEG Layer 3;\
-       file_extensions=.mp3;\
-       icon=mpeg;\
-       action=application;\
-       application=mpg123 %s
-
-audio/vnd.rn-realaudio: \
-       description=RealAudio File;\    
-       file_extensions=.ra
-
diff --git a/etc/extralib/README b/etc/extralib/README
new file mode 100755 (executable)
index 0000000..d43e611
--- /dev/null
@@ -0,0 +1 @@
+This directory is for local jar files.
index 136953b..ea73b3f 100755 (executable)
@@ -81,7 +81,7 @@ log4j.appender.GlobalA.layout=org.apache.log4j.PatternLayout
 log4j.appender.GlobalA.layout.ConversionPattern=%d [%p] %c %x %m%n
 
 log4j.appender.UtilityA=org.apache.log4j.RollingFileAppender
-log4j.appender.UtilityA.File=${log.home}/global.log
+log4j.appender.UtilityA.File=${log.home}/utility.log
 log4j.appender.UtilityA.layout=org.apache.log4j.PatternLayout
 log4j.appender.UtilityA.layout.ConversionPattern=%d [%p] %c %x %m%n
 
diff --git a/etc/open/comment.template b/etc/open/comment.template
deleted file mode 100755 (executable)
index cd693b8..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-<html>
-<head>
-  <title>${lang("comment.htmltitle")}</title>
-  <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
-</head>
-<body bgcolor="white" text="black" link="#006600" vlink="#009900" alink="red">
-
-<form action="${config["Producer.OpenAction"]}" method=post>
-<input type="hidden" name="do" value="inscomment">
-
-<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="silver">
-  <tr>
-    <td bgcolor="#663399" colspan="3">
-      <font color="White"><b>${lang("comment.header")}</b></font>
-    </td>
-  </tr>
-  <tr>
-    <td bgcolor="#003300" colspan="3">
-      <p>
-        <font color="white"">
-          ${lang("comment.note")}
-<if data.passwd>          
-          <br>
-          ${data.passwd}
-</if>          
-        </font>
-      </p>
-
-    </td>
-  </tr>
-  <tr>
-    <td bgcolor="#663399" colspan="3">
-      <font face="Helvetica, Arial" color="white" size=+2><b>${lang("comment.formtitle")}</b></font>
-    </td>
-  </tr>
-<if data.passwd>          
-  <tr>
-    <td><td>${lang("comment.password")}:</td>
-    <td><input type="text" name="passwd" size="10"></td>
-  </tr>
-</if>
-  <tr>
-    <td>
-      <b>${lang("comment.title")}:</b>
-    </td>
-    <td colspan="2">
-      <input type="text" name="title" size="45" maxlength="45"> <font size="-1" color="#663399">(${lang("required")})</font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      <b>${lang("comment.name")}:</b>
-    </td>
-    <td colspan="2">
-      <input type="text" name="creator" size="20" maxlength="45"> <font size="-1" color="#663399">(${lang("required")})</font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("comment.email")}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="email" size="30" maxlength="80"> <font size="-1">(<i>${lang("optional")}</i>)</font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("comment.url")}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="main_url" size="40" maxlength="160" value="http://"> <font size="-1">(<i>${lang("optional")}</i>)</font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("comment.phone")}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="phone" size="30" maxlength="80"> <font size="-1">(<i>${lang("optional")}</i>)</font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("comment.address")}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="address" size="40" maxlength="160"><font size="-1"> <i>(${lang("optional")})</i></font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("comment.language")}:
-    </td>
-    <td colspan="2">
-      <select name="to_language">
-        <list extra.languagePopUpData as l>
-        <option value="${l.key}">${l.value}</option>
-        </list>
-      </select>
-      <font size="-1"><i>(${lang("optional")})</i></font>
-    </td>
-  </tr>
-  <tr>
-    <td valign="top">
-      <b>${lang("comment.text")}:</b>
-    </td>
-    <td bgcolor="#003300" colspan="2">
-      &nbsp;<textarea name="description" rows="20" cols="60" wrap=virtual></textarea>
-      <br><br>
-    </td>
-  </tr>
-  <tr>
-    <td>&nbsp;
-    </td>
-    <td bgcolor="#663399" valign="top" align="center">
-      <br>
-      &nbsp;<input type="submit" value="${lang("comment.submit")}"><br>
-
-    </td>
-    <td bgcolor="#003300" valign="top" align="center">
-      <br>
-      &nbsp;<input type="reset" value="${lang("comment.reset")}"><br>
-      <input type="hidden" name="to_media" value="${data.aid}">
-      <br>
-    </td>
-  </tr>
-</table>
-
-</form>
-
-</body>
-</html>
diff --git a/etc/open/comment_done.template b/etc/open/comment_done.template
deleted file mode 100755 (executable)
index 0b7ebf6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-  <title>${lang("commentdone.htmltitle")}</title>
-</head>
-
-<body bgcolor="White" text="Black" link="#006600" vlink="#009900" alink="Red">
-
-<table width="100%" border="0" cellspacing="0" cellpadding="10">
-  <tr>
-    <td valign="top" align="center" bgcolor="#663399">
-      <font color="White"><b>${lang("commentdone.thanks")}</b></font
-    </td>
-  </tr>
-  <tr>
-    <td bgcolor="#cccccc" align="center">
-
-        <br>
-                ${lang("commentdone.wait")}
-        <br>
-                ${lang("commentdone.criteria")}
-        <br>
-        <em>${lang("commentdone.stay_calm")}</em><br>
-        <br>
-
-    </td>
-  </tr>
-  <tr>
-    <td valign="top" align="center" bgcolor="#663399">
-      <a href="javascript:history.go(-2)"><font color="White"><b>&gt;&gt; ${lang("commentdone.back")}</b></font></a>
-    </td>
-  </tr>
-</table>
-
-</body>
-</html>
diff --git a/etc/open/comment_dupe.template b/etc/open/comment_dupe.template
deleted file mode 100755 (executable)
index 3f44874..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-  <title>${lang("commentdupe.htmltitle")}</title>
-</head>
-
-<body bgcolor="White" text="Black" link="white" vlink="#009900" alink="Red">
-
-<table width="100%" border="0" cellspacing="0" cellpadding="10">
-  <tr>
-    <td valign="top" align="center" bgcolor="#663399">
-      <font color="White"><b>
-        ${lang("commentdupe.title")}
-      </b></font
-    </td>
-  </tr>
-  <tr>
-    <td bgcolor="003300" width=70%>
-      <font color="White">
-        <br>
-                    ${lang("commentdupe.explanation")}
-        <br>
-        <center><em>${lang("commentdupe.no_panic")}</em></center><br>
-        <br>
-      </font>
-    </td>
-  </tr>
-  <tr>
-    <td valign="top" align="center" bgcolor="#663399">
-      <a href="javascript:history.go(-2)"><font color="White"><b>&gt;&gt; ${lang("commentdupe.back")}</b></font></a>
-    </td>
-  </tr>
-</table>
-
-</body>
-</html>
diff --git a/etc/open/donetranslation.template b/etc/open/donetranslation.template
new file mode 100755 (executable)
index 0000000..5041125
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+  <title>${lang("postingdone.htmltitle")}</title> 
+  <style type="text/css" media="all">@import "forms.css";</style>
+</head>
+
+<body marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" bgcolor="#dddddd">
+
+  <table cellspacing="0" cellpadding="0" width="100%">
+    <tr>
+      <td colspan="3" width="100%">&nbsp;</td>
+    </tr>
+    <tr>
+      <td width="20%" bgcolor="#ff9966">
+        &nbsp;&nbsp;<a href="${config["Producer.ProductionHost"]}/index.shtml" class="startlink">start &gt;&gt;</a>
+      </td>
+      <td width="60%" bgcolor="#ff9966" class="pad4x">
+        <span id="title"><b>${lang("translation.donetitle")}</b></span>
+      </td>
+      <td width="20%">&nbsp;</td>
+    </tr>
+    <tr>
+      <td colspan="3" class="pad4x"><span class="size2px">&nbsp;</span></td>
+    </tr>
+    <tr>
+      <td align="right">&nbsp;</td>
+      <td class="pad5L">
+        <br>
+                ${lang("translationdone.info")}<br>
+        <br>
+        <em>${lang("commentdone.stay_calm")}</em><br>
+        <br>
+      </td>
+      <td>&nbsp;</td>
+    </tr>
+    
+    <tr>
+      <td align="right">&nbsp;</td>
+      <td class="pad5Lx" bgcolor="#eecc99">
+        <if referer>
+          <a href="${referer}"><b>${lang("postingdone.back")} &gt;&gt;</b></a>
+        </if>
+      </td>
+      <td bgcolor="#eecc99">&nbsp;</td>
+    </tr>
+    <tr>
+      <td colspan="3" class="pad2x">&nbsp;<br><br></td>
+    </tr>
+  </table>
+
+
+</body>
+</html>
index 4cbeba2..5bd19d7 100755 (executable)
@@ -2,16 +2,7 @@
 <html>
 <head>
 <title>${lang("posting.htmltitle")}</title>
-<meta name="description" content="${lang("posting.meta.description")}">
-<meta name="author" content="${lang("posting.meta.author")}">
-<meta name="keywords" content="${lang("posting.meta.keywords")}">
-<!--<meta name="date" content="### Date ###Time">-->
-<meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">
-<meta name="robots" content="index">
-<meta name="robots" content="follow">
-
-
-    <style type="text/css"> body {background-image: none;} </style>
+<style type="text/css"> body {background-image: none;} </style>
 
 
 <style type="text/css">
@@ -186,21 +177,20 @@ color: red;
 <body bgcolor="#dddddd">
 
 <function showErrors(aField)>
-<comment>
-function to display error message at the input box  // occam, 2003-06-09
-</comment>
-<if errors>
-<list errors as e>
-<if e.field==aField>
-${lang(e.message + "." + e.field)}
-</if>
-</list>
-</if>
+  <comment>
+    function to display error message at the input box  // occam, 2003-06-09
+  </comment>
+
+  <if errors>
+    <list errors as e>
+      <if e.field==aField>
+        ${lang(e.message + "." + e.field)}
+      </if>
+    </list>
+  </if>
 </function>
 
     <if errors>
-
-
           Your input had the following errors:<br><br>
           <list errors as e>
             <font color="red">
@@ -208,10 +198,11 @@ ${lang(e.message + "." + e.field)}
                 ${lang("content."+e.field)}:
               </if>
               ${lang(e.message)} <br>
+              <list e.parameters as p>
+                ${utility.prettyEncodeHTML(p)}<br>
+              </list>
             </font>
           </list>
-
-
     </if>
 
 
@@ -404,6 +395,12 @@ ${lang("posting.text.info")}
 <else>
 <small><strong>(${lang("required")})</strong></small>
 </if>
+<p>${lang("posting.html")}</p>
+<select name="is_html">
+<option value="0" <if is_html!="1">selected</if>>plain text</option>
+<option value="1" <if is_html=="1">selected</if>>html</option>
+</select>
+
 </div>
 
 <h2>
@@ -415,27 +412,72 @@ ${lang("posting.step05")}
 ${lang("posting.media")}
 </h4>
 <p>
+<small>${lang("optional")}</small>
+</p>
+<list attachments as a>
+    <hr>
+    <h4>
+      ${utility.encodeHTML(a.filename)}
+    </h4>
+    <input type="checkbox" name="${a.fieldname}_cancel"> ${lang("posting.media.cancel")}
+
+    <h4>
+      ${lang("posting.media.title")} 
+    </h4>
+    <input type="text" class="preq" name="${a.fieldname}_title" size="40" maxlength="80" value="${utility.encodeHTML(a.title)}">
+</list>
+
+<p>
 ${lang("posting.media.info")}
 </p>
 <p>
 ${lang("posting.media.howto")}
 </p>
 
-      <list mediaitems as m>
-<h4>
-${lang("posting.media.media")} ${m}
-</h4>
-<input type="file" name="media${m}">
-
-<h4>
-${lang("posting.media.title")} ${m}
-</h4>
-<input type="text" class="preq" name="media${m}_title" size="40" maxlength="80" value="">
+<list mediaitems as m>
+    <hr>
+    <h4>
+    ${lang("posting.media.media")} ${m}
+    </h4>
+    <input type="file" name="media${m}">
+    
+    <h4>
+    ${lang("posting.media.title")} ${m}
+    </h4>
+    <input type="text" class="preq" name="media${m}_title" size="40" maxlength="80" value="">
 </list>
 
-<p>
-<small>${lang("optional")}</small>
-</p>
+<if config["Localizer.OpenSession.AllowFTPUploads"]!="0">
+  <if config["Localizer.OpenSession.AllowFTPUploadSelection"]!="0" && ftpfiles>
+    <hr>
+    <h4>
+      ${lang("posting.media.ftpmedia")}
+    </h4>
+    <select name="ftpupload">
+      <option value="">&nbsp;</option>
+      <list ftpfiles as f>
+        <option value="${utility.encodeHTML(f)}">${f}</option>
+      </list>
+    </select>
+    
+    <h4>
+      ${lang("posting.media.title")} 
+    </h4>
+    <input type="text" class="preq" name="ftpupload_title" size="40" maxlength="80" value="">
+  <else>
+    <hr>
+    <h4>
+      ${lang("posting.media.ftpmedia")}
+    </h4>
+    <input type="text" name="ftpupload"  size="40" maxlength="80" value="">
+    <h4>
+      ${lang("posting.media.title")} 
+    </h4>
+    <input type="text" class="preq" name="ftpupload_title" size="40" maxlength="80" value="">
+  </if>  
+</if>  
+
+
 </div>
 
 <h2>
index 817edcd..dc73ede 100755 (executable)
@@ -164,7 +164,18 @@ ${lang("comment.formtitle")}
 </h1>
 
     <if errors>
-<p class="error">${lang("comment.errors")}</p>
+          Your input had the following errors:<br><br>
+          <list errors as e>
+            <font color="red">
+              <if e.field>
+                ${lang("content."+e.field)}:
+              </if>
+              ${lang(e.message)} <br>
+              <list e.parameters as p>
+                ${utility.prettyEncodeHTML(p)}<br>
+              </list>
+            </font>
+          </list>
    </if>
 
 <form enctype="multipart/form-data" action="${actionURL}&do=opensession&sessiontype=comment" method="post">
@@ -257,7 +268,25 @@ ${lang("comment.language")}
 <h2>
 ${lang("posting.step03")}
 </h2>
+
+
 <div class="pformstep02">
+
+<list attachments as a>
+    <hr>
+    <h4>
+      ${utility.encodeHTML(a.filename)}
+    </h4>
+    <input type="checkbox" name="${a.fieldname}_cancel"> ${lang("posting.media.cancel")}
+
+    <h4>
+      ${lang("posting.media.title")} 
+    </h4>
+    <input type="text" class="preq" name="${a.fieldname}_title" size="40" maxlength="80" value="${utility.encodeHTML(a.title)}">
+</list>
+
+<hr>
+
 <table>
   <tr>
     <td>
@@ -303,6 +332,36 @@ ${lang("posting.step03")}
   </tr>
 </table>
 
+<if config["Localizer.OpenSession.AllowFTPUploads"]!="0">
+  <if config["Localizer.OpenSession.AllowFTPUploadSelection"]!="0" && ftpfiles>
+    <hr>
+    <h4>
+      ${lang("posting.media.ftpmedia")}
+    </h4>
+    <select name="ftpupload">
+      <option value="">&nbsp;</option>
+      <list ftpfiles as f>
+        <option value="${utility.encodeHTML(f)}">${f}</option>
+      </list>
+    </select>
+    
+    <h4>
+      ${lang("posting.media.title")} 
+    </h4>
+    <input type="text" class="preq" name="ftpupload_title" size="40" maxlength="80" value="">
+  <else>
+    <hr>
+    <h4>
+      ${lang("posting.media.ftpmedia")}
+    </h4>
+    <input type="text" name="ftpupload"  size="40" maxlength="80" value="">
+    <h4>
+      ${lang("posting.media.title")} 
+    </h4>
+    <input type="text" class="preq" name="ftpupload_title" size="40" maxlength="80" value="">
+  </if>  
+</if>  
+
 </div>
 
 
diff --git a/etc/open/edittranslation.template b/etc/open/edittranslation.template
new file mode 100755 (executable)
index 0000000..1d37ef9
--- /dev/null
@@ -0,0 +1,334 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//DE">
+<html>
+<head>
+<title>${lang("posting.htmltitle")}</title>
+<meta name="description" content="${lang("posting.meta.description")}">
+<meta name="author" content="${lang("posting.meta.author")}">
+<meta name="keywords" content="${lang("posting.meta.keywords")}">
+<!--<meta name="date" content="### Date ###Time">-->
+<meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">
+<meta name="robots" content="index">
+<meta name="robots" content="follow">
+
+
+    <style type="text/css"> body {background-image: none;} </style>
+
+
+<style type="text/css">
+<!--
+
+body {
+margin: 6px; background: #dddddd ;
+}
+h1, h2, h3, h4, h5, h6, p, li, dt, dd, div, td, blockquote
+{
+font-family:arial, helvetica, sans-serif;
+}
+
+.pformbox
+{
+border: none;
+margin: none;
+padding-left: 10px;
+padding-right: 10px;
+padding-bottom: 0px;
+padding-top: 0px;
+}
+
+h1 { padding-bottom: 0px; margin-bottom: 0px;}
+h2
+{
+padding-bottom: 0px;
+margin-bottom: 0px;
+padding: 2px;
+border: none;
+margin: none;
+border-top: 1px solid black;
+border-left: 1px solid black;
+border-right: 1px solid black;
+background-color: #003366;
+color: white;
+}
+h3 { padding-bottom: 0px; margin-bottom: 0px;}
+h4 { padding-bottom: 0px; margin-bottom: 0px;}
+
+.pdiscl
+{
+padding: 4px;
+margin-top: 6px;
+margin-bottom: 6px;
+
+border-color: #FFF;
+border-width: 2px;
+border-style: solid;
+}
+
+.pformstep01
+{
+margin: none;
+border: none;
+padding: 8px;
+margin-top: 0px;
+margin-bottom: 6px;
+background-color: #FAFAD2;
+border-color: gray;
+border-width: 1px;
+border-style: solid;
+}
+.pformstep02
+{
+margin: none;
+border: none;
+padding: 8px;
+margin-top: 0px;
+margin-bottom: 6px;
+background-color: #FAFAD2;
+border-color: gray;
+border-width: 1px;
+border-style: solid;
+}
+.pformstep03
+{
+margin: none;
+border: none;
+padding: 8px;
+margin-top: 0px;
+margin-bottom: 6px;
+background-color: #FAFAD2;
+border-color: gray;
+border-width: 1px;
+border-style: solid;
+}
+.pformstep04
+{
+margin: none;
+border: none;
+padding: 8px;
+margin-top: 0px;
+margin-bottom: 6px;
+background-color: #FAFAD2;
+border-color: gray;
+border-width: 1px;
+border-style: solid;
+}
+.pformstep05
+{
+margin: none;
+border: none;
+padding: 8px;
+margin-top: 0px;
+margin-bottom: 6px;
+background-color: #FAFAD2;
+border-color: gray;
+border-width: 1px;
+border-style: solid;
+}
+.pformstep06
+{
+margin: none;
+border: none;
+padding: 8px;
+margin-top: 0px;
+margin-bottom: 6px;
+background-color: #FFFFFF;
+border-color: gray;
+border-width: 1px;
+border-style: solid;
+}
+
+input.psubmit
+{
+padding: 5px;
+border: 2px solid green;
+background-color: #6F0;
+}
+
+input.preset
+{
+padding: 5px;
+border: 2px solid red;
+background-color: #F96;
+}
+
+.pbuttons {
+text-align: right;
+}
+
+input
+{
+background-color: #efefef;
+}
+
+textarea
+{
+background-color: #efefef;
+}
+
+
+input.preq
+{
+background-color: #ffffff;
+}
+textarea.preq
+{
+background-color: #ffffff;
+}
+
+.error {
+color: red;
+}
+
+-->
+</style>
+
+</head>
+
+<body bgcolor="#dddddd">
+
+<function showErrors(aField)>
+<comment>
+function to display error message at the input box  // occam, 2003-06-09
+</comment>
+<if errors>
+<list errors as e>
+<if e.field==aField>
+${lang(e.message + "." + e.field)}
+</if>
+</list>
+</if>
+</function>
+
+    <if errors>
+
+
+          Your input had the following errors:<br><br>
+          <list errors as e>
+            <font color="red">
+              <if e.field>
+                ${lang("content."+e.field)}:
+              </if>
+              ${lang(e.message)} <br>
+            </font>
+          </list>
+
+
+    </if>
+
+
+<comment>
+
+<div class="pdiscl">
+<include "disclaimer.inc.de">
+</div>
+
+</comment>
+
+<div class="pformbox">
+
+<h1>
+${lang("translation.form.title")}
+</h1>
+<form enctype="multipart/form-data" action="${actionURL}&do=opensession&sessiontype=translation&to_content=${parent.id}" method="post">
+
+    <if errors>
+<p class="error">${lang("posting.errors")}</p>
+    </if>
+
+
+
+<h2>
+${lang("translation.step01")} <!-- info about translation -->
+</h2>
+
+<div class="pformstep01">
+<!-- LANG -->
+<h4>
+${lang("translation.language")}
+</h4>
+<select name="to_language">
+<list languages as l>
+<option value="${l.id}">${l.name}</option>
+</list>
+</select>
+<br />
+${lang("translation.to_language.other")}
+<input type="text" name="subtitle" value="${utility.encodeHTML(subtitle)}">
+
+<!-- AUTOR -->
+<h4>
+${lang("translation.author")}
+</h4>
+<input type="text" class="preq" name="creator" value="${utility.encodeHTML(creator)}" size="45" maxlength="45"> 
+<if errors>
+<big class="error"><call showErrors("creator")></big>
+<else>
+<small><strong>(${lang("required")})</strong></small>
+</if>
+</div>
+
+
+<h2>
+${lang("translation.step02")}
+</h2>
+<div class="pformstep02">
+<!-- TITEL -->
+<h4>
+${lang("translation.title")}
+</h4>
+<p><i>${utility.encodeHTML(parent.title)}</i></p>
+<p>
+<input type="text" class="preq" name="title" size="45" maxlength="45" value="${utility.encodeHTML(title)}">
+<if errors>
+<big class="error"><call showErrors("title")></big>
+</if>
+</p>
+
+
+<!-- ABSTRACT -->
+<h4>
+${lang("translation.abstract")}
+</h4>
+<p><i>${utility.encodeHTML(parent.description)}</i></p>
+<textarea name="description" class="preq" rows="10" cols="74" wrap=virtual>${utility.encodeHTML(description)}</textarea>
+<if errors>
+<big class="error"><call showErrors("description")></big>
+</if>
+<!-- CONTENT -->
+<h4>
+${lang("translation.text")}
+</h4>
+<p><i>${utility.encodeHTML(parent.content_data)}</i></p>
+<textarea name="content_data" class="preq" rows="35" cols="74" wrap="soft">${utility.encodeHTML(content_data)}</textarea>
+<if errors>
+<big class="error"><call showErrors("content_data")></big>
+</if>
+<p>
+${lang("translation.is_html")}
+</p>
+<select name="is_html">
+              <option value="0" <if parent.is_html!="1">selected</if>>plain/text</option>
+              <option value="1" <if parent.is_html=="1">selected</if>>text/html</option>
+</select>
+
+
+</div>
+
+<h2>
+${lang("translation.step03")}
+</h2>
+<div class="pformstep03">
+
+<p>
+${lang("translation.submit.info")}
+</p>
+<div class="pbuttons">
+<input type="submit" name="post" class="psubmit" value="${lang("posting.submit")}">
+<input type="reset" class="preset" value="${lang("posting.reset")}">
+</div>
+
+</div>
+
+</form>
+</div>
+</body>
+</html>
index 6965788..b4e01c3 100755 (executable)
@@ -20,7 +20,7 @@
   <tr>
     <td>
       <p>
-      <p align="center"><font color="red">${data.date} -- ${data.errorstring}</font>
+      <p align="center"><font color="red">${errorstring}</font>
       <p>
     </td>
   </tr>
diff --git a/etc/open/posting.template b/etc/open/posting.template
deleted file mode 100755 (executable)
index 6d35bee..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//DE">
-<html>
-<head>
-  <title>${lang("posting.htmltitle")}</title>
-  <meta name="description" content="${lang("posting.meta.description")}">
-  <meta name="author" content="${lang("posting.meta.author")}">
-  <meta name="keywords" content="${lang("posting.meta.keywords")}">
-  <!--<meta name="date" content="### Date ###Time">-->
-  <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
-  <meta name="robots" content="index">
-  <meta name="robots" content="follow">
-
-  <link rel=stylesheet type="text/css" href="${config["Producer.ProductionHost"]}/style/formate.css">
-</head>
-
-<body bgcolor="White" text="Black" link="#006600" vlink="#006600" alink="Red">
-
-
-<table width="99%" border="0" cellspacing="0" cellpadding="8" bgcolor="silver">
-  <tr>
-    <td align="left" bgcolor="#663399" colspan="3">
-      <a href="#form"><font face="Verdana, Arial, Helvetica, sans-serif" size="-2" color="white"><b>&gt;&gt; ${lang("posting.jump_to_form")}</b></font></a>
-    <br>
-    </td>
-  </tr>
-  <tr>
-    <td align="center" colspan="3">
-      <font size="+1" face="Verdana, Arial, Helvetica, sans-serif"><b>${lang("posting.title")}</b></font><br>
-    </td>
-  </tr>
-  <tr>
-    <td colspan="3" bgcolor="white">
-
-<include "open/disclaimer.inc.de">
-<if data.passwd>          
-
-<br>${data.passwd}
-</if>
-<br><br>
-<a name="form"></a>
-    </td>
-  </tr>
-<form action="${config["Producer.OpenAction"]}?do=addposting" method="post">
-  <tr>
-    <td><b>${lang("posting.nr_of_media")}</b> <br>
-      ${lang("posting.nr_of_media.info")}</td>
-    <td colspan="2"><input type="text" name="medianum" value="${data.medianum}">&nbsp;<input type="submit" value="${lang("posting.nr_of_media.submit")}">
-  </tr>
-</form>
-
-
-<form enctype="multipart/form-data" action="${config["Producer.OpenAction"]}?do=insposting" method="post">
-  <tr>
-    <td bgcolor="#663399" colspan="3">
-      <center><font size="+2" face="Helvetica, Arial,sans-serif" color="white"><b>${lang("posting.form.title")}</b></font></center>
-    </td>
-  </tr>
-<if data.passwd>          
-    <tr>
-      <td>${lang("posting.password")}</td>
-      <td><input type="text" name="passwd" size="10"></td>
-    </tr>
-</if>
-  <tr>
-    <td valign="top">
-      ${lang("posting.title")}:<br>
-      <font size="-2">${lang("posting.title.info")}</font>
-    </td>
-    <td colspan="2" bgcolor="#003300">
-      <input type="text" name="title" size="45" maxlength="45" value=""> <font size="-1" color="white"><br>(${lang("required")})</font>
-    </td>
-  </tr>
-    <tr>
-        <td valign="top">
-            ${lang("posting.topic")}:<br>
-  <font size="-2">${lang("posting.topic.info")}</font>
-        </td>
-       <td colspan="2">
-       <select name="to_topic" size="3" multiple>
-       <list extra.themenPopupData as t>
-       <option value="${t.key}" <list data.to_topic as to><if (t.key == to)>selected</if></list>>${t.value}</option>
-       </list>
-       </select>
-       &nbsp;&nbsp;<font size="-1">(<i>${lang("optional")}</i>)</font>
-       </td>
-    </tr>
-  <tr>
-    <td valign="top">
-      ${lang("posting.author")}:
-    </td>
-    <td colspan="2" bgcolor="#003300">
-      <input type="text" name="creator" size="45" maxlength="45"> <font size="-1" color="white"><br>${lang("required")}</font>
-    </td>
-  </tr>
-  <tr>
-    <td valign="top">
-      ${lang("posting.abstract")}:</b> <br>
-      <font size="-2">${lang("posting.abstract.info")}</font>
-    </td>
-    <td colspan="2" bgcolor="#003300">
-      <textarea name="description" rows="6" cols="55" wrap=virtual></textarea>
-      <font size="-1" color="white"><br>${lang("posting.abstract.constraint")}</font>
-    </td>
-  </tr>
-  <tr>
-    <td colspan="3" bgcolor="#FFFFFF">
-    <font face="Helvetica, Arial, sans-serif" size=-1 color="#222222">
-    ${lang("posting.contact.info")}
-    </font>
-    </td>
-  </tr>
-
-  <tr>
-    <td>
-      ${lang("posting.email")}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="creator_email" size="55" maxlength="80" value=""><br>
-                             <font size="-1">(<i>${lang("optional")}</i>)</font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("posting.url")}:
-    </td>
-    <td colspan="2">
-    <input type="text" name="creator_main_url" size="55" maxlength="160" value="http://"><br>
-     <font size="-1">(<i>${lang("optional")}</i>)</font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("posting.address")}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="creator_address" size="55" maxlength="160" value=""><br>
-                          <font size="-1"> <i>(${lang("optional")})</i></font>
-    </td>
-  </tr>
-  <tr>
-    <td>
-      ${lang("posting.phone")}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="creator_phone" size="20" maxlength="20" value=""><br>
-      <font size="-1">(<i>${lang("optional")}</i>)</font>
-    </td>
-  </tr>
-
-          <tr>
-            <td colspan="3" bgcolor="#FFFFFF">&nbsp;</td>
-  </tr>
-
-  <tr>
-    <td>
-      ${lang("posting.language")}:
-    </td>
-    <td colspan="2">
-      <select name="to_language">
-        <list extra.languagePopUpData as l>
-        <option value="${l.key}">${l.value}</option>
-        </list>
-      </select>
-      &nbsp;&nbsp;<font size="-1"><i>(${lang("optional")})</i></font>
-    </td>
-  </tr>
-  <tr>
-    <td valign="top">
-      ${lang("posting.text")}:<br>
-      <font size="-2">${lang("posting.text.info")}</font>
-    </td>
-    <td bgcolor="#003300" colspan="2">
-      &nbsp; <textarea name="content_data" rows="20" cols="55" wrap="soft"></textarea>
-      <br><br>
-    </td>
-  </tr>
-
-  <tr>
-    <td>
-      <b>${lang("posting.media")}:</b>
-    </td>
-    <td colspan="2">
-      ${lang("posting.media.info")}<br>
-      <font size="-2">${lang("posting.media.howto")}</font>
-    </td>
-  </tr>
-<list data.mediafields as m>
-  <tr>
-    <td>
-    ${lang("posting.media.title")} ${m}:
-    </td>
-    <td colspan="2">
-      <input type="text" name="media_title${m}" size="40" maxlength="80" value=""><br>
-    </td>
-  </tr>
-  <tr>
-    <td>${lang("posting.media.media")} ${m}</td>
-    <td colspan="2">
-      <INPUT TYPE="file" NAME="media${m}">
-      <br><font size="-1">(<i>${lang("optional")}</i>)</font>
-    </td>
-  </tr>
-</list>
-
-  <tr>
-          <td colspan="3" bgcolor="#FFFFFF">&nbsp;</td>
-  </tr>
-
-  <tr>
-    <td align="left" valign="center">
-
-            <!-- text -->
-            ${lang("posting.submit.info")}
-
-      <br>
-      ${lang("posting.criteria")}<br>
-
-    </td>
-    <td bgcolor="#663399" valign="center" align="center">
-  <input type="submit" value="${lang("posting.submit")}">
-
-    </td>
-    <td bgcolor="#003300" valign="center" align="center">
-      <input type="reset" value="${lang("posting.reset")}">
-    </td>
-  </tr>
-</form>
-
-</table>
-
-
-
-</body>
-</html>
diff --git a/etc/open/posting_done.template b/etc/open/posting_done.template
deleted file mode 100755 (executable)
index baee9ee..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-  <title>${lang("postingdone.htmltitle")}</title>
-</head>
-
-<body bgcolor="White" text="Black" link="#006600" vlink="#666666" alink="Red">
-
-<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="#cccccc">
-  <tr>
-    <td align="center" bgcolor="#666666">
-    <font color="White">${lang("postingdone.title")}</font></td>
-  </tr>
-  <tr>
-    <td bgcolor="#eeeeee"><font color="#000000">
-
-
-<br>
-${lang("postingdone.info")}
-<br><br>
-<center><EM>${lang("postingdone.stay_calm")}</EM></center><br><br>
-
-  </font>
-  </td>
-</tr>
-
-<tr>
-  <td valign="top" align="center" bgcolor="#666666">
-  <a href="javascript:history.go(-2)"><font color="White"><b>&gt;&gt; ${lang("postingdone.back")}</b></font></a>
-    </td>
-  </tr>
-</table>
-</body>
-</html>
diff --git a/etc/open/posting_dupe.template b/etc/open/posting_dupe.template
deleted file mode 100755 (executable)
index e5329e3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-  <title>${lang("postingdupe.htmltitle")}</title>
-</head>
-
-<body bgcolor="White" text="Black" link="white" vlink="#009900" alink="Red">
-
-<table width="100%" border="0" cellspacing="0" cellpadding="10">
-  <tr>
-    <td valign="top" align="center" bgcolor="#663399">
-      <font color="White"><b>
-        ${lang("postingdupe.title")}
-      </b></font
-    </td>
-  </tr>
-  <tr>
-    <td bgcolor="003300" width=70%>
-      <font color="White">
-        <br>
-                    ${lang("postingdupe.explanation")}
-        <br>
-        <center><em>${lang("postingdupe.no_panic")}</em></center><br>
-        <br>
-      </font>
-    </td>
-  </tr>
-  <tr>
-    <td valign="top" align="center" bgcolor="#663399">
-      <a href="javascript:history.go(-2)"><font color="White"><b>&gt;&gt; ${lang("postingdupe.back")}</b></font></a>
-    </td>
-  </tr>
-</table>
-
-</body>
-</html>
diff --git a/etc/open/prepare_mail.template b/etc/open/prepare_mail.template
deleted file mode 100755 (executable)
index a5446ba..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-  <title>${lang("email.prepare.htmltitle")}</title>
-</head>
-
-<body bgcolor="White" text="Black" link="#006600" vlink="#666666" alink="Red">
-
-<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="#cccccc">
-  <tr>
-    <td align="center" bgcolor="#666666">
-    <font color="White">${lang("email.prepare.title")}</font></td>
-  </tr>
-  <tr>
-    <td bgcolor="#eeeeee"><font color="#000000">
-${lang("email.prepare.description")}<BR>
-<FORM method="post" action="${config["Producer.OpenAction"]}">
-<input type="hidden" name="do" value="mail">
-<input type="hidden" name="mail_aid" value="${data.mail_aid}">
-${lang("email.prepare.sendtowhom")}  <input type="text" size="20" name="mail_to" value="${data.mail_to}"> <BR> 
-${lang("email.prepare.from.email")} <input type="text" size="20" name="mail_from" value="${data.mail_from}"> <BR> 
-${lang("email.prepare.from.name")} <input type="text" size="20" name="mail_from_name" value="${data.mail_from_name}"> <BR> 
-${lang("email.prepare.comment")} <textarea name="mail_comment" rows="5" cols="40">${data.mail_comment}</textarea><BR>
-${lang("email.prepare.chooselanguage")}
-<select name="mail_language">
-  <option value="en" <if data.mail_language=="en">selected</if>>english</option>
-  <option value="de" <if data.mail_language=="de">selected</if>>deutsch</option>  
-</select>
-
-<input type="submit" value='${lang("email.prepare.send")}'> 
-</FORM>
-  </td>
-</tr>
-
-<tr>
-  <td valign="top" align="center" bgcolor="#666666">
-  <a href="javascript:history.go(-1)"><font color="White"><b>&gt;&gt; ${lang("postingdone.back")}</b></font></a>
-    </td>
-  </tr>
-</table>
-</body>
-</html>
diff --git a/etc/open/preparemail.template b/etc/open/preparemail.template
new file mode 100755 (executable)
index 0000000..74f2e2b
--- /dev/null
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+  <title>${lang("email.prepare.htmltitle")}</title>
+</head>
+
+<body bgcolor="White" text="Black" link="#006600" vlink="#666666" alink="Red">
+
+<table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor="#cccccc">
+  <tr>
+    <td align="center" bgcolor="#666666">
+    <font color="White">${lang("email.prepare.title")}</font></td>
+  </tr>
+  <tr>
+    <td bgcolor="#eeeeee"><font color="#000000">
+${lang("email.prepare.description")}<BR>
+<FORM method="post" action="${actionURL}&do=opensession&sessiontype=email">
+<!-- <input type="hidden" name="mail_aid" value="${email.aid}">-->
+${lang("email.prepare.sendtowhom")}  <input type="text" size="20" name="mail_to" value="${mail_to}"> <BR> 
+${lang("email.prepare.from.email")} <input type="text" size="20" name="mail_from" value="${mail_from}"> <BR> 
+${lang("email.prepare.from.name")} <input type="text" size="20" name="mail_from_name" value="${mail_from_name}"> <BR> 
+${lang("email.prepare.comment")} <textarea name="mail_comment" rows="5" cols="40">${mail_comment}</textarea><BR>
+${lang("email.prepare.chooselanguage")}
+<select name="mail_language">
+  <option value="en" <if mail_language=="en">selected</if>>english</option>
+  <option value="de" <if mail_language=="de">selected</if>>deutsch</option>  
+</select>
+
+<input type="submit" value='${lang("email.prepare.send")}'> 
+</FORM>
+  </td>
+</tr>
+
+<tr>
+  <td valign="top" align="center" bgcolor="#666666">
+  <a href="javascript:history.go(-1)"><font color="White"><b>&gt;&gt; ${lang("postingdone.back")}</b></font></a>
+    </td>
+  </tr>
+</table>
+</body>
+</html>
index 1a416e8..01e42d4 100755 (executable)
@@ -182,11 +182,9 @@ ${lang("search.sort_how")}
         <if h.hasVideo == "y">
           <img src="${config["Producer.PublicationHost"]}/img/video_big.gif">&nbsp;
         </if>
-        <if h.hasImages == "y">
         <list h.images as image>
           <img src="${config["Producer.PublicationHost"]}/${image}"><br>
         </list>
-        </if>
       &nbsp;
   </td>
     </tr>
index 6965788..9a7081a 100755 (executable)
@@ -4,7 +4,6 @@
     <link rel="stylesheet" type="text/css" href="${config.docRoot}/style/admin.css">
 </head>
 <body>
-<include "head.template">
 <table width="100%" border="0" align="center">
   <tr class="grey">
     <td>
@@ -20,7 +19,7 @@
   <tr>
     <td>
       <p>
-      <p align="center"><font color="red">${data.date} -- ${data.errorstring}</font>
+      <p align="center"><font color="red">${errorstring}</font>
       <p>
     </td>
   </tr>
@@ -32,6 +31,5 @@
     </td>
   </tr>
 </table>
-<include "foot.template">
 </body>
 </html>
index 6965788..5e8bcac 100755 (executable)
   </tr>
   <tr>
     <td>
-      <p>${lang("error.text", config["Mir.Tech-email.address"], config["Mir.Tech-email.name"])}
-    </td>
-  </tr>
-  <tr>
-    <td>
       <p>
-      <p align="center"><font color="red">${data.date} -- ${data.errorstring}</font>
+      <p align="center"><font color="red">${lang("media.error.unsupportedformat", mimetype)}</font>
       <p>
     </td>
   </tr>
diff --git a/etc/producer/RSS-full.template b/etc/producer/RSS-full.template
new file mode 100755 (executable)
index 0000000..be4f4df
--- /dev/null
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<function mediaitem(item, icon, w, h)>
+        <assign title=item.title>
+        <td><a href="${item["publish_server"]}${item["publish_path"]}">
+        <img src="${icon}" alt="${title}" <if w && h>width="${w}" height="${h}"</if>></a>
+        <if title != ""><br><span>${title}</span></if></td>
+</function>
+
+<function imageitem(image)>
+        <call mediaitem(image, iconprefix+image["icon_path"], image["icon_width"], image["icon_height"])>
+</function>
+
+<function otheritem(media)>
+        <call mediaitem(media, iconprefix+"/img/" + media["big_icon"], "", "")>
+</function>
+
+
+<rdf:RDF
+  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+  xmlns="http://purl.org/rss/1.0/"
+  xmlns:dc="http://purl.org/dc/elements/1.1/"
+  xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
+  xmlns:content="http://purl.org/rss/1.0/modules/content/"
+>
+
+  <channel rdf:about="${utility.encodeHTML(channelidentifier)}">
+    <title>${utility.encodeHTML(channeltitle)}</title>
+    <link>${utility.encodeHTML(channelidentifier)}</link>
+    <if channeldescription>
+      <description>${utility.encodeHTML(channeldescription)}</description>
+    </if>
+    <if channelpublisher>
+      <dc:publisher>${utility.encodeHTML(channelpublisher)}</dc:publisher>
+    </if>
+    <dc:rights>Open Content License, http://www.opencontent.org</dc:rights>
+    <dc:date>${config.now.formatted.dc}</dc:date>
+    <items>
+      <rdf:Seq>
+        <list articles as i>  
+          <rdf:li rdf:resource="${articleprefix}/${i.date.formatted["yyyy"]}/${i.date.formatted["MM"]}/${i.id}.shtml" />
+        </list>
+      </rdf:Seq>
+    </items>
+  </channel>
+
+  <list articles as i>    
+    <item rdf:about="${articleprefix}/${i.date.formatted["yyyy"]}/${i.date.formatted["MM"]}/${i.id}.shtml">
+      <title>${utility.encodeHTML(i.title)}</title>
+      <link>${articleprefix}/${i.date.formatted["yyyy"]}/${i.date.formatted["MM"]}/${i.id}.shtml</link>    
+      <description>${utility.encodeHTML(i.description_parsed)}</description>
+      <assign media=i>
+      <content:encoded>
+        <![CDATA[
+            <if media.to_media_images || media.to_media_video || media.to_media_audio || media.to_media_other>
+            <table>
+            <assign n = 0>
+            
+            <list media.to_media_images as image>
+                    <if n == "0"> <tr> </if>
+                    <call imageitem(image)>
+                    <if n == "000"> <assign n = 0> </tr> <else> <assign n = n + 0> </if>
+            </list>
+            
+            <list media.to_media_video as video>
+                    <if n == "0"> <tr> </if>
+                    <call otheritem(video)>
+                    <if n == "000"> <assign n = 0> </tr> <else> <assign n = n + 0> </if>
+            </list>
+            
+            <list media.to_media_audio as audio>
+                    <if n == "0"> <tr> </if>
+                    <call otheritem(audio)>
+                    <if n == "000"> <assign n = 0> </tr> <else> <assign n = n + 0> </if>
+            </list>
+            
+            <list media.to_media_other as other>
+                    <if n == "0"> <tr> </if>
+                    <call otheritem(other)>
+                    <if n == "000"> <assign n = 0> </tr> <else> <assign n = n + 0> </if>
+            </list>
+            
+            </table></if>
+        ]]>
+        ${utility.encodeHTML(i.content_data_parsed)}
+      </content:encoded>
+      <dc:date>${i.creationdate.formatted["yyyy-MM-dd'T'HH:mm'-07:00'"]}</dc:date>
+      <if i.creator>
+        <dc:creator>${utility.encodeHTML(i.creator)}</dc:creator>
+      </if>
+      <if i.creator_main_url>
+        <dc:link>${utility.encodeXML(i.creator_main_url)}</dc:link>
+      </if>
+      <dc:language>${i.language.code}</dc:language>
+    </item>
+  </list>
+</rdf:RDF>
index 89017b3..0be5075 100755 (executable)
@@ -9,26 +9,25 @@
 
   <channel rdf:about="${utility.encodeXML(channelidentifier)}">
     <title>${utility.encodeXML(channeltitle)}</title>
-    <link>${utility.encodeXML(channellink)}</link>
+    <link>${utility.encodeXML(channelidentifier)}</link>
     <description>${utility.encodeXML(channeldescription)}</description>
     <dc:publisher>${utility.encodeXML(channelpublisher)}</dc:publisher>
     <dc:rights>Open Content License, http://www.opencontent.org</dc:rights>
-    <dc:date>${config.now.dc}</dc:date>
+    <dc:date>${config.now.formatted.dc}</dc:date>
     <items>
       <rdf:Seq>
-        <list articles as i>  
-          <rdf:li rdf:resource="${config["Producer.PublicationHost"]}${config.docRoot}${i.publish_path}${i.id}.shtml" />
+        <list articles as i>   
+         <rdf:li rdf:resource="${articleprefix}/${i.date.formatted["yyyy"]}/${i.date.formatted["MM"]}/${i.id}.shtml" />
         </list>
       </rdf:Seq>
     </items>
   </channel>
 
-  <list articles as i>    
-    <item rdf:about="${config["Producer.ProductionHost"]}${config.docRoot}${i.publish_path}${i.id}.shtml">
-      <title>${i.title}</title>
-        <link>${config["Producer.ProductionHost"]}${config.docRoot}${i.publish_path}${i.id}.shtml</link>
-        <description>${i.description_sentence}</description>
-      <dc:date>${i.webdb_create_dc}+0200</dc:date>
+  <list articles as i>                 
+    <item rdf:about="${articleprefix}/${i.date.formatted["yyyy"]}/${i.date.formatted["MM"]}/${i.id}.shtml">
+        <title>${i.title}</title>
+        <link>${articleprefix}/${i.date.formatted["yyyy"]}/${i.date.formatted["MM"]}/${i.id}.shtml</link>    
+      <dc:date>${i.creationdate.formatted["yyyy-MM-dd'T'HH:mm'-07:00'"]}</dc:date>
     </item>
   </list>
   
index 8c862ab..68986c1 100755 (executable)
         </b></font>
       </td></tr></table>
       <table cellpadding="30" cellspacing="0" border="0" width="80%"><tr><td>
+        <table border="0" cellpadding="2" cellspacing="0" width="100%"><tr><td bgcolor="#669999">
+          &nbsp;<!--#include virtual="/languagebar/${article.to_original.date.formatted.yyyy}/${article.to_original.date.formatted.MM}/${article.to_original.id}.shtml"-->
+        </td></tr></table> 
+       <br>
+        <table border="0" cellpadding="2" cellspacing="0" width="100%"><tr><td bgcolor="#669999">
+         &nbsp;<a href="${config.openAction}?do=opensession&sessiontype=translation&to_content=${article.to_original.id}"><font color="#dddddd">${lang("general.addtranslation")} &gt;&gt;</font></a>
+        </td></tr></table>
+
         <br>
         <h2>${article.title}</h2>
 
-        <p><i><font size="-1">${article.creator}, ${article.creationdate.formatted["dd.MM.yyyy HH:mm"]}</font></i></p>
+        <p><i><font size="-1">${article.to_original.creator} <if article.to_original.id!=article.id>(${lang("general.translatedby", article.creator)})</if><if article.creator || article.to_original.creator>, </if>${article.to_original.creationdate.formatted["dd.MM.yyyy HH:mm"]}</font></i></p>
         <br>
         <p>${article.description_parsed}</p>
 
-        <if article.mediacount!=0>
+        <if article.to_original.mediacount!=0>
           <!-- media -->
-          <list article.to_media_audio as media>
+          <list article.to_original.to_media_audio as media>
           <p>
                  <img src="../../../img/${media["big_icon"]}" border="0" alt="">&nbsp;
                  <a href="${media["publish_server"]}${media["publish_path"]}">
           </p>
           </list>
 
-                 <list article.to_media_video as media>
+         <list article.to_original.to_media_video as media>
           <p>
           <img src="../../../img/${media["big_icon"]}" border="0" alt="">
           <a href="${media["publish_server"]}${media["publish_path"]}">
           </p>
           </list>
 
-                 <list article.to_media_other as media>
+         <list article.to_original.to_media_other as media>
           <p>
           <img src="../../../img/${media["big_icon"]}" border="0" alt="">
           <a href="${media["publish_server"]}${media["publish_path"]}">
           </p>
           </list>
 
-          <list article.to_media_images as image>
+          <list article.to_original.to_media_images as image>
           <p>
           <img src="${image["publish_server"]}${image["publish_path"]}"
           border="0" width="${image["img_width"]}"
           </td></tr></table>
 <br>
           <table border="0" cellpadding="2" cellspacing="0" width="100%"><tr><td bgcolor="#83B0B0">
-      &nbsp;<a href="${config["Producer.OpenAction"]}?do=opensession&sessiontype=comment&to_media=${article.id}&language=${language.code}">
+      &nbsp;<a href="${config["Producer.OpenAction"]}?do=opensession&sessiontype=comment&to_media=${article.to_original.id}&language=${language.code}">
             <font color="#dddddd" size="+1"><b>${lang("article.addcomment")} &gt;&gt;</b></font></a>
           </td></tr></table>
-          <if article.to_comments>
+          <if article.to_original.to_comments>
             <table border="0" cellpadding="10" cellspacing="0" width="100%"><tr><td bgcolor="#A8D0D0">
-              <list article.to_comments as c>
+              <list article.to_original.to_comments as c>
                 <br>
                 <font size="+1"><b>${utility.encodeHTML(c.title)}</b></font><br>
                 <i><font size="-1">${c.creationdate.formatted["dd.MM.yyyy - HH:mm"]}</font></i><br>
index febb8bf..5133f19 100755 (executable)
           <td>
             <br>
               <!--- articles --->
-                <list articles as i>
+                <list articles as a>
+                 <assign aorig=a.to_original>
+                 <if languagepreference>
+                   <assign i=a.to_translation(languagepreference)>
+                 <else>
+                   <assign i=a>
+                 </if>
+
                   <p><font size="+1">
                   <a href="${config["Producer.DocRoot"]}/${language.code}/${i.date.formatted["yyyy'/'MM"]}/${i.id}.shtml"><b>${i.title}</b></a>
                   </font><br>
-                     <font size="-2">${i.creator}, ${i.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p>
+                     <font size="-2">${aorig.creator} <if aorig.id!=i.id>(${lang("general.translatedby", i.creator)})</if><if i.creator || aorig.creator>, </if> ${aorig.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p> 
                   <p><font size="-1">
-                  <if i.to_media_audio >
+                  <if aorig.to_media_audio >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_audio[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_audio[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_video >
+                  <if aorig.to_media_video >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_video[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_video[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_other >
+                  <if aorig.to_media_other >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_other[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_other[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_images >
+                  <if aorig.to_media_images >
                   <img align="left" vspace="4" hspace="8"
-                       src="${i.to_media_images[0]["icon_path"]}"
-                       width="${i.to_media_images[0]["icon_width"]}"
-                       height="${i.to_media_images[0]["icon_height"]}"
-                       border=0 alt="${i.to_media_images[0]["title"]}">
+                       src="${aorig.to_media_images[0]["icon_path"]}"
+                       width="${aorig.to_media_images[0]["icon_width"]}"
+                       height="${aorig.to_media_images[0]["icon_height"]}"
+                       border=0 alt="${aorig.to_media_images[0]["title"]}">
                   </if>
                   ${i.description_parsed}
                   <br clear="all">
diff --git a/etc/producer/languagebar.template b/etc/producer/languagebar.template
new file mode 100755 (executable)
index 0000000..000b3dc
--- /dev/null
@@ -0,0 +1,4 @@
+<a href="${config["Producer.DocRoot"]}/${language.code}/${article.to_original.date.formatted["yyyy'/'MM"]}/${article.to_original.id}.shtml"><font color="#dddddd">${article.to_original.languagename}</font></a>
+<list article.to_original.to_translations as a>
+  | <a href="${config["Producer.DocRoot"]}/${language.code}/${a.date.formatted["yyyy'/'MM"]}/${a.id}.shtml"><font color="#dddddd">${a.languagename}</font></a>
+</list>
index b55b4c2..f359e16 100755 (executable)
           </list> 
       </td></tr></table>
       <br>
-      
+      <table cellpadding="8" cellspacing="0" border="0" width="100%" bgcolor="#cc9999"><tr><td>
+        <b>${lang("navigation.syndication")}</b><br />
+       <font size="-2">
+       <a href="${config["Producer.DocRoot"]}/main-features.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${lang("syndication.features")}</a><br />   
+       <a href="${config["Producer.DocRoot"]}/main-features-content.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${lang("syndication.features")} ${lang("syndication.full")}</a><br />       
+       <a href="${config["Producer.DocRoot"]}/main-newswire.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${lang("syndication.newswire")}</a><br />   
+       <a href="${config["Producer.DocRoot"]}/main-newswire.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${lang("syndication.newswire")} ${lang("syndication.full")}</a><br />       
+       <br />
+       <list topics as t>
+         <a href="${config["Producer.DocRoot"]}/${t.filename}-features.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${t.title}  ${lang("syndication.features")}</a><br />    
+         <a href="${config["Producer.DocRoot"]}/${t.filename}-features-content.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${t.title}  ${lang("syndication.features")} ${lang("syndication.full")}</a><br />        
+         <a href="${config["Producer.DocRoot"]}/${t.filename}-newswire.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${t.title}  ${lang("syndication.newswire")}</a><br />    
+         <a href="${config["Producer.DocRoot"]}/${t.filename}-newswire.rss"><img src="${config["Producer.DocRoot"]}/img/xml.gif" alt="XML" /> ${t.title}  ${lang("syndication.newswire")} ${lang("syndication.full")}</a><br />        
+       </list>
+        </font>
+      </td></tr></table>
+<br />
index 5031978..0cca4af 100755 (executable)
           <td>
             <br>
               <!--- articles --->
-                <list articles as i>
+                <list articles as a>
+                 <assign aorig=a.to_original>
+                 <if languagepreference>
+                   <assign i=a.to_translation(languagepreference)>
+                 <else>
+                   <assign i=a>
+                 </if>
+
+
                   <p><font size="+1">
                   <a href="${config["Producer.DocRoot"]}/${language.code}/${i.date.formatted["yyyy'/'MM"]}/${i.id}.shtml"><b>${i.title}</b></a>
                   </font><br>
-                     <font size="-2">${i.creator}, ${i.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p>
+                     <font size="-2">${aorig.creator} <if aorig.id!=i.id>(${lang("general.translatedby", i.creator)})</if><if i.creator || aorig.creator>, </if> ${aorig.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p>
                   <p><font size="-1">
-                  <if i.to_media_audio >
+                  <if aorig.to_media_audio >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_audio[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_audio[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_video >
+                  <if aorig.to_media_video >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_video[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_video[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_other >
+                  <if aorig.to_media_other >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_other[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_other[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_images >
+                  <if aorig.to_media_images >
                   <img align="left" vspace="4" hspace="8"
-                       src="${i.to_media_images[0]["icon_path"]}"
-                       width="${i.to_media_images[0]["icon_width"]}"
-                       height="${i.to_media_images[0]["icon_height"]}"
-                       border=0 alt="${i.to_media_images[0]["title"]}">
+                       src="${aorig.to_media_images[0]["icon_path"]}"
+                       width="${aorig.to_media_images[0]["icon_width"]}"
+                       height="${aorig.to_media_images[0]["icon_height"]}"
+                       border=0 alt="${aorig.to_media_images[0]["title"]}">
                   </if>
                   ${i.description_parsed}
                   <br clear="all">
index 4311a74..9b0bbd6 100755 (executable)
@@ -13,7 +13,7 @@
 <producers>
   <nodedefinition name="Language">
     <parameters>
-      <string name="languagecondition" defaultvalue=""/>
+      <string name="languagecondition" defaultvalue="code != 'ot'"/>
       <string name="bundle" defaultvalue="bundles.producer" />
       <node name="sub"/>    
     </parameters>
       <Enumerate key="language" table="language" selection="${languagecondition}" order="code">
         <Resource bundle="${bundle}" key="lang" language="${language.code}"/>
         <Define key="pathprefix" value="${language.code}" />
+        <Define key="languagepreference" value="${language.code}" />
         <sub/>
+        <If condition="language.code=='en'">
+          <then>
+            <Define key="pathprefix" value="or" />
+            <Define key="languagepreference" value="" />
+            <sub/>
+          </then>
+        </If>
       </Enumerate>
     </definition>
   </nodedefinition>
+
+  <nodedefinition name="RSSChannel">
+    <parameters>
+      <string name="articleSelection"/>
+      <string name="extratables" defaultvalue="none" />
+      <integer name="limit" defaultvalue="15"/>
+      <string name="channelidentifier" defaultvalue=""/>
+      <string name="channelfilename"/>
+      <string name="channeltitle"/>
+      <string name="articleprefix" defaultvalue="${config['Producer.PublicationHost']}/or" />
+      <string name="iconprefix" defaultvalue="${config['Producer.PublicationHost']}/icon" />
+      <string name="channelpublisher" defaultvalue="${config['Mir.Name']}" />
+      <string name="encoding" defaultvalue="UTF-8" />
+      <string name="channeldescription" defaultvalue=""/>
+      <string name="generator" defaultvalue="/RSS.template" />
+    </parameters>
+
+    <definition>
+      <If condition="extratables == 'none' ">
+        <then>
+          <List key="articles" table="content c" selection="${articleSelection}" order = "c.webdb_create desc, c.date desc" limit="limit" />
+        </then>
+        <else>
+          <List key="articles" table="content c" selection="${articleSelection}" order = "c.webdb_create desc, c.date desc" limit="limit" extratables="${extratables}" />
+        </else>
+      </If>
+      <If condition="channeldescription==''">
+        <then>
+         <Define key="channeldescription" value="${channeltitle}"/>
+       </then>
+      </If>
+      <If condition="channelidentifier==''">
+        <then>
+          <Define key="channelidentifier" value="${config['Producer.PublicationHost']}/or/${channelfilename}"/>
+        </then>
+      </If>
+
+      <Generate
+         parameters="${encoding}"
+         generator="${generator}"
+        destination="${config.storageRoot}/${channelfilename}"/>
+    </definition>
+  </nodedefinition>
+
+  <nodedefinition name="RSSChannelBundle">
+    <parameters>
+      <string name="extratables" defaultvalue="none" />
+      <string name="selection" defaultvalue="c.is_published='1'" />  
+      <string name="basefilename" defaultvalue="main" />
+    </parameters>
+    <definition>
+      <!-- newswire -->
+      <RSSChannel
+        articleSelection="(c.to_article_type in (${articletype.newswire}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.newswire}))) and ${selection}"
+        channelfilename="${basefilename}-newswire.rss"
+        channeltitle="${config['Mir.Name']} ${basefilename} newswire"
+        limit="20"
+       extratables="${extratables}"
+      />
+      <RSSChannel
+        articleSelection="(c.to_article_type in (${articletype.newswire}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.newsire}))) and ${selection}"
+        channelfilename="${basefilename}-newswire-content.rss"
+        channeltitle="${config['Mir.Name']} ${basefilename} newswire"
+        limit="20"
+        generator="RSS-full.template"
+       extratables="${extratables}"
+      />    
+      <!-- features -->
+      <RSSChannel
+        articleSelection="(c.to_article_type in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}))) and ${selection}"
+        channelfilename="${basefilename}-features.rss"
+        channeltitle="${config['Mir.Name']} ${basefilename} features"
+        limit="20"
+       extratables="${extratables}"
+      />
+      <RSSChannel
+        articleSelection="(c.to_article_type in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}) or (c.to_article_type=${articletype.translation} and c.to_original.to_articletype in (${articletype.feature},${articletype.startspecial},${articletype.topicspecial}))) and ${selection}"
+        channelfilename="${basefilename}-features-content.rss"
+        channeltitle="${config['Mir.Name']} ${basefilename} features"
+        limit="20"
+        generator="RSS-full.template"
+       extratables="${extratables}"
+      />
+    </definition>
+  </nodedefinition>
+
  
   <producer name="articles">
     <verbs>
     <body>
       <Enumerate key="article" table="content" selection="${verbcondition}"
                   limit="limit" order="webdb_create desc">
+        <Enumerate 
+            key="media" table="image" 
+            selection="exists (select * from content_x_media where media_id=images.id and content_id=${article.id})
+               or      exists (select * from comment_x_media, comment
+                           where comment_id = comment.id and media_id=images.id and comment.to_media=${article.id})"
+            order="id desc">
+            
+           <GenerateMedia key="media" />
+        </Enumerate>
+        <Enumerate 
+            key="media" table="video" 
+            selection="exists (select * from content_x_media where media_id=video.id and content_id=${article.id})
+               or      exists (select * from comment_x_media, comment
+                           where comment_id = comment.id and media_id=video.id and comment.to_media=${article.id})"
+            order="id desc">
+           <GenerateMedia key="media" />
+        </Enumerate>
+        <Enumerate 
+            key="media" table="audio" 
+            selection="exists (select * from content_x_media where media_id=audio.id and content_id=${article.id})
+               or      exists (select * from comment_x_media, comment
+                                       where comment_id = comment.id and media_id=audio.id and comment.to_media=${article.id})"
+            order="id desc">
+            
+           <GenerateMedia key="media" />
+        </Enumerate>
+        <Enumerate 
+            key="media" table="otherMedia" 
+            selection="exists (select * from content_x_media where media_id=other_media.id and content_id=${article.id})
+               or      exists (select * from comment_x_media, comment
+                                       where comment_id = comment.id and media_id=other_media.id and comment.to_media=${article.id})"
+            order="id desc">
+            
+           <GenerateMedia key="media" />
+        </Enumerate>
+
         <If condition="article.is_published == '1'">
           <then>
             <Language>
               <Generate 
                 generator="/article.template" 
                 destination="${config.storageRoot}/${pathprefix}/${article.date.formatted.yyyy}/${article.date.formatted.MM}/${article.id}.shtml"/>
-
-    <!-- commented out features
-    
-              <PDFPreFormat 
-                key="article" 
-                numLinesBetweenImages="3" 
-                charWidthCM="0.19" 
-                pixelWidthCM="0.035"
-                contentAreaWidthCM="16" 
-                lineHeightCM="0.5" />
-              <Generate 
-                generator="/printablecontent.template" 
-                destination="${config.storageRoot}/${pathprefix}/${article.date.formatted.yyyy}/${article.date.formatted.MM}/${article.id}.fo"
-                parameters="UTF-8" />
-              <PDFGenerate
-                generator="${config.storageRoot}/${pathprefix}/${article.date.formatted.yyyy}/${article.date.formatted.MM}/${article.id}.fo"
-                destination="${config.storageRoot}/${pathprefix}/${article.date.formatted.yyyy}/${article.date.formatted.MM}/${article.id}.pdf"
-                stylesheet="${config['Producer.HTML2FOStyleSheet']}" /> 
-                
-      -->
-                
              </Language>
+            <Generate 
+                generator="/languagebar.template" 
+                destination="${config.storageRoot}/languagebar/${article.to_original.date.formatted.yyyy}/${article.to_original.date.formatted.MM}/${article.to_original.id}.shtml"/>  
              <IndexContent key="article" pathToIndex="${config['IndexPath']}"/>
           </then>
           <else>
       </Enumerate>
     </body>
   </producer>  
+
+  <producer name="syndication">
+    <verbs>
+      <verb name="generate" />
+    </verbs>
+    <body>
+      <!-- the main features and newswire -->
+      <RSSChannelBundle />
+      
+      <!-- the topic features and newswires -->
+      <Enumerate key="topic" table="topic">
+        <RSSChannelBundle
+          basefilename="${topic.filename}"
+         selection="c.id=cxt.content_id and cxt.topic_id = ${topic.id}"
+          extratables="content_x_topic cxt"
+        />
+      </Enumerate>
+      
+      
+
+    </body>
+
+  </producer>
+
+  <producer name="radicalendar">
+    <verbs>
+      <verb name="pull" />
+    </verbs>
+    <body>
+      <!-- groupname you will see as the value of "group" in the url for your radicalendar page, -->
+      <!--      gmtoffset is in minutes                                                                 -->
+      <Radicalendar key="calendar" groupname="_imc" gmtoffset="60"  />
+      <Generate 
+        generator="/radicalendar.template" 
+        destination="${config.storageRoot}/calendarinclude.shtml"/>
+
+
+    </body>
+  </producer>
+
   
 </producers>
 
diff --git a/etc/producer/radicalendar.template b/etc/producer/radicalendar.template
new file mode 100755 (executable)
index 0000000..8d6ca17
--- /dev/null
@@ -0,0 +1,5 @@
+<ul class="radicalendar">
+  <list calendar as c>
+  <li>${c.eventdate} <a href="http://www.radicalendar.org/group/${c.shortname}/all/display/${c.objectid}/index.php?fulldate=${c.eventdate}">${c.title}</a>  ${c.eventtime} <br /> ${c.description}   
+  </list>
+</ul>
index 750dceb..ce639bf 100755 (executable)
-<comment>\r
-  This file contains several routines to be used in the templates\r
-</comment>\r
-\r
-<function showArticleUrl(aPrefix, anArticle, aText, aCSSClass)>\r
-  <a class="${aCSSClass}" href="/${aPrefix}/${anArticle.date.formatted.yyyy}/${anArticle.date.formatted.MM}/${anArticle.id}.shtml">${aText}</a>\r
-</function>\r
-\r
-<function showSafeText(aText)>\r
-  ${utility.encodeHTML(aText)}\r
-</function>\r
-\r
-<function showSafeTextOrDefault(aField, aDefault)>\r
-  <if aField>\r
-    <call showSafeText(aField)>\r
-  <else>\r
-    ${aDefault}\r
-  </if>\r
-</function>\r
+<comment>
+  This file contains several routines to be used in the templates
+</comment>
+
+<function showArticleUrl(aPrefix, anArticle, aText, aCSSClass)>
+  <a class="${aCSSClass}" href="/${aPrefix}/${anArticle.date.formatted.yyyy}/${anArticle.date.formatted.MM}/${anArticle.id}.shtml">${aText}</a>
+</function>
+
+<function showSafeText(aText)>
+  ${utility.encodeHTML(aText)}
+</function>
+
+<function showSafeTextOrDefault(aField, aDefault)>
+  <if aField>
+    <call showSafeText(aField)>
+  <else>
+    ${aDefault}
+  </if>
+</function>
 
 <function showAddCommentLink(anArticle, aText, aLanguage)>
   <a href="${config["Producer.OpenAction"]}?do=addcomment&aid=${anArticle.id}&language=${aLanguage.code}">${aText}</a>
 </function>
-                            \r
-<function showArticleMedia(anArticle)>\r
- <!-- media -->\r
-   <list anArticle.to_media_audio as audio>\r
-      <br>\r
-      <br>\r
-      <a href="${audio["publish_server"]}${audio["publish_path"]}">\r
-          <img src="/images/${video["big_icon"]}" border="0" alt="">\r
-          <call showSafeText(audio.title)> - <call showSafeText(audio.descr)>\r
-      </a>\r
-   </list>\r
-\r
-   <list anArticle.to_media_video as video>\r
-      <br>\r
-      <br>\r
-      <a href="${video["publish_server"]}${video["publish_path"]}">\r
-          <img src="/images/${video["big_icon"]}" border="0" alt="">\r
-          <call showSafeText(video.title)> - <call showSafeText(video.descr)>\r
-      </a>\r
-   </list>\r
-\r
-   <list anArticle.to_media_other as other>\r
-      <br>\r
-      <br>\r
-      <a href="${other["publish_server"]}${other["publish_path"]}">\r
-          <img src="/images/${other["big_icon"]}" border="0" alt="">\r
-          <call showSafeText(other.title)> - <call showSafeText(other.descr)>\r
-      </a>\r
-   </list>\r
-\r
-   <list anArticle.to_media_images as image>\r
-      <br>\r
-      <br>\r
-      <img src="${image["publish_server"]}${image["publish_path"]}"\r
-              border="0" width="${image["img_width"]}"\r
-              height="${image["img_height"]}" alt="${image["title"]}"><br>\r
-      <i><call showSafeText(image.title)></i>\r
-   </list>\r
- <!-- media -->\r
-</function>\r
-\r
-<function showArticleMediaIcons(anArticle)>\r
+                            
+<function showArticleMedia(anArticle)>
+ <!-- media -->
+   <list anArticle.to_media_audio as audio>
+      <br>
+      <br>
+      <a href="${audio["publish_server"]}${audio["publish_path"]}">
+          <img src="/images/${video["big_icon"]}" border="0" alt="">
+          <call showSafeText(audio.title)> - <call showSafeText(audio.descr)>
+      </a>
+   </list>
+
+   <list anArticle.to_media_video as video>
+      <br>
+      <br>
+      <a href="${video["publish_server"]}${video["publish_path"]}">
+          <img src="/images/${video["big_icon"]}" border="0" alt="">
+          <call showSafeText(video.title)> - <call showSafeText(video.descr)>
+      </a>
+   </list>
+
+   <list anArticle.to_media_other as other>
+      <br>
+      <br>
+      <a href="${other["publish_server"]}${other["publish_path"]}">
+          <img src="/images/${other["big_icon"]}" border="0" alt="">
+          <call showSafeText(other.title)> - <call showSafeText(other.descr)>
+      </a>
+   </list>
+
+   <list anArticle.to_media_images as image>
+      <br>
+      <br>
+      <img src="${image["publish_server"]}${image["publish_path"]}"
+              border="0" width="${image["img_width"]}"
+              height="${image["img_height"]}" alt="${image["title"]}"><br>
+      <i><call showSafeText(image.title)></i>
+   </list>
+ <!-- media -->
+</function>
+
+<function showArticleMediaIcons(anArticle)>
     <if anArticle.to_media_audio > 
       <img src="/img/${anArticle.to_media_audio[0]["big_icon"]}">
     </if> 
-    \r
+    
     <if anArticle.to_media_video > 
       <img src="/img/${anArticle.to_media_video[0]["big_icon"]}">
     </if> 
-    \r
+    
     <if anArticle.to_media_other > 
       <img src="/img/${anArticle.to_media_other[0]["big_icon"]}">
     </if> 
-    \r
+    
       <if anArticle.to_media_images >
         <img src="${anArticle.to_media_images[0]["icon_path"]}"
           width="${anArticle.to_media_images[0]["icon_width"]}"
           height="${anArticle.to_media_images[0]["icon_height"]}"
           border=0 alt="${anArticle.to_media_images[0]["title"]}">
       </if> 
-</function>\r
-\r
-<function showArticleAsFeature(anArticle)>\r
+</function>
+
+<function showArticleAsFeature(anArticle)>
   <h3><call showSafeText(anArticle.title)></h3>
   <h4><i><call showSafeText(anArticle.creator)>, ${anArticle.creationdate.formatted["dd.MM.yyyy HH:mm"]}</i></h4>
     <p>      
         <call showArticleMediaIcons(anArticle)>
-        ${anArticle.description_parsed} \r
+        ${anArticle.description_parsed} 
     </p>
-\r
+
     <p align="right">
       [<call showArticleUrl(pathprefix, anArticle, lang("general.readarticle"), "featurelink")>]
     </p>
-</function>\r
-\r
-\r
-<function showArticleAsNewswire(anArticle)>\r
+</function>
+
+
+<function showArticleAsNewswire(anArticle)>
   <img alt=${anArticle.to_media_icon["icon_alt"]} border="0" height="10"
-       src="${anArticle.to_media_icon["tiny_icon"]}" width="12"> \r
-       \r
+       src="${anArticle.to_media_icon["tiny_icon"]}" width="12"> 
+       
   <call showArticleUrl(pathprefix, anArticle, anArticle.title, "")><br />
   <font size="-2">${n.creationdate.formatted["dd-MM-yyyy HH:mm"]}</font><br>
-</function>\r
-\r
+</function>
+
index 8f2e841..afdd74b 100755 (executable)
       <!-- /breaking news -->
 
     <!--- start-special --->
-      <list startspecial as s>
-         <table width="100%" border="0" cellspacing="0" cellpadding="10" bgcolor="#eeeeee"><tr><td>
+      <list startspecial as ss>
+        <assign sorig=ss.to_original>
+        <if languagepreference>
+          <assign s=ss.to_translation(languagepreference)>
+        <else>
+          <assign s=ss>
+        </if>
+        <table width="100%" border="0" cellspacing="0" cellpadding="10" bgcolor="#eeeeee"><tr><td>
              <p><font size="+2">
              <a href="${config["Producer.DocRoot"]}/${language.code}/${s.date.formatted["yyyy'/'MM"]}/${s.id}.shtml"><b>${s.title}</b></a>
              </font><br>
-                <font size="-2">${s.creator}, ${s.creationdate.formatted["dd.MM.yyyy - HH:mm"]}</font></p>
+                <font size="-2">${sorig.creator} <if sorig.id!=s.id>(${lang("general.translatedby", s.creator)})</if><if s.creator || sorig.creator>, </if>  ${sorig.creationdate.formatted["dd.MM.yyyy - HH:mm"]}</font></p>
              <p><font size="-1">
-              <if s.to_media_audio >
+              <if sorig.to_media_audio >
                 <img align="left" vspace="4" hspace="8"
-                  src="${config["Producer.DocRoot"]}/img/${s.to_media_audio[0]["big_icon"]}">
+                  src="${config["Producer.DocRoot"]}/img/${sorig.to_media_audio[0]["big_icon"]}">
               </if>
-              <if s.to_media_video >
+              <if sorig.to_media_video >
                 <img align="left" vspace="4" hspace="8"
-                  src="${config["Producer.DocRoot"]}/img/${s.to_media_video[0]["big_icon"]}">
+                  src="${config["Producer.DocRoot"]}/img/${sorig.to_media_video[0]["big_icon"]}">
               </if>
-              <if s.to_media_other >
+              <if sorig.to_media_other >
                 <img align="left" vspace="4" hspace="8"
-                   src="${config["Producer.DocRoot"]}/img/${s.to_media_other[0]["big_icon"]}">
+                   src="${config["Producer.DocRoot"]}/img/${sorig.to_media_other[0]["big_icon"]}">
               </if>
-              <if s.to_media_images >
+              <if sorig.to_media_images >
                 <img align="left" vspace="4" hspace="8"
-                  src="${s.to_media_images[0]["icon_path"]}"
-                  width="${s.to_media_images[0]["icon_width"]}"
-                  height="${s.to_media_images[0]["icon_height"]}"
-                  border=0 alt="${s.to_media_images[0]["title"]}">
+                  src="${sorig.to_media_images[0]["icon_path"]}"
+                  width="${sorig.to_media_images[0]["icon_width"]}"
+                  height="${sorig.to_media_images[0]["icon_height"]}"
+                  border=0 alt="${sorig.to_media_images[0]["title"]}">
               </if>
               ${s.description_parsed}
           <br clear="all">
 
 
     <!--- features ---> <comment></comment>
-      <list features as i>
+      <list features as f>
+       <assign forig=f.to_original>
+        <if languagepreference>
+          <assign i=f.to_translation(languagepreference)>
+        <else>
+          <assign i=f>
+        </if>
+
         <p><font size="+1">
         <a href="${config["Producer.DocRoot"]}/${language.code}/${i.date.formatted["yyyy'/'MM"]}/${i.id}.shtml"><b>${i.title}</b></a>
         </font><br>
-           <font size="-2">${i.creator}, ${i.creationdate.formatted["dd.MM.yyyy -  HH:mm"]}</font></p>
+           <font size="-2">${forig.creator} <if forig.id!=i.id>(${lang("general.translatedby", i.creator)})</if><if i.creator || forig.creator>, </if> ${forig.creationdate.formatted["dd.MM.yyyy -  HH:mm"]}</font></p>
         <p><font size="-1">
-        <if i.to_media_audio >
+        <if forig.to_media_audio >
         <img align="left" vspace="4" hspace="8"
-             src="${config["Producer.DocRoot"]}/img/${i.to_media_audio[0]["big_icon"]}">
+             src="${config["Producer.DocRoot"]}/img/${forig.to_media_audio[0]["big_icon"]}">
         </if>
-        <if i.to_media_video >
+        <if forig.to_media_video >
         <img align="left" vspace="4" hspace="8"
-             src="${config["Producer.DocRoot"]}/img/${i.to_media_video[0]["big_icon"]}">
+             src="${config["Producer.DocRoot"]}/img/${forig.to_media_video[0]["big_icon"]}">
         </if>
-        <if i.to_media_other >
+        <if forig.to_media_other >
         <img align="left" vspace="4" hspace="8"
-             src="${config["Producer.DocRoot"]}/img/${i.to_media_other[0]["big_icon"]}">
+             src="${config["Producer.DocRoot"]}/img/${forig.to_media_other[0]["big_icon"]}">
         </if>
-        <if i.to_media_images >
+        <if forig.to_media_images >
         <img align="left" vspace="4" hspace="8"
-             src="${i.to_media_images[0]["icon_path"]}"
-             width="${i.to_media_images[0]["icon_width"]}"
-             height="${i.to_media_images[0]["icon_height"]}"
-             border=0 alt="${i.to_media_images[0]["title"]}">
+             src="${forig.to_media_images[0]["icon_path"]}"
+             width="${forig.to_media_images[0]["icon_width"]}"
+             height="${forig.to_media_images[0]["icon_height"]}"
+             border=0 alt="${forig.to_media_images[0]["title"]}">
         </if>
         ${i.description_parsed}
         <br clear="all">
 
           <!-- newswire -->
           <font size="-1">
-            <list newswire as n>
-                         <img src="${n.to_media_icon.tiny_icon}" alt="${n.to_media_icon.icon_alt}" height="10" width="12">
+            <list newswire as nn>
+             <assign norig=nn.to_original>
+             <if languagepreference>
+               <assign n=nn.to_translation(languagepreference)>
+             <else>
+                <assign n=nn>
+             </if>
+           
+
+             <img src="${norig.to_media_icon.tiny_icon}" alt="${norig.to_media_icon.icon_alt}" height="10" width="12">
               <a href="${config["Producer.DocRoot"]}/${language.code}/${n.date.formatted.yyyy}/${n.date.formatted.MM}/${n.id}.shtml">${n.title}</a>
               <br>
               <font size="-2">${n.creationdate.formatted["dd-MM-yyyy HH:mm"]}</font><br>
index ed357e0..d30b89f 100755 (executable)
             <br>
               <!--- topic-special ---> <comment></comment>
                                <if (batch.current.index==batch.first.index)>
-                               <list special as s>
+                               <list special as ss>
+                                 <assign sorig=ss.to_original> 
+                                 <if languagepreference>
+                                   <assign s=ss.to_translation(languagepreference)>
+                                 <else>
+                                   <assign s=ss>
+                                 </if>
+
                    <table width="100%" border="0" cellspacing="0" cellpadding="10" bgcolor="#eeeeee"><tr><td>
                        <p><font size="+2">
                        <a href="${config["Producer.DocRoot"]}/${language.code}/${s.date.formatted["yyyy'/'MM"]}/${s.id}.shtml"><b>${s.title}</b></a>
                        </font><br>
-                          <font size="-2">${s.creator}, ${s.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p>
+                          <font size="-2">${sorig.creator} <if sorig.id!=s.id>(${lang("general.translatedby", s.creator)})</if><if s.creator || sorig.creator>, </if> ${sorig.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p>
                        <p><font size="-1">
-                        <if s.to_media_audio >
+                        <if sorig.to_media_audio >
                           <img align="left" vspace="4" hspace="8"
-                            src="${config["Producer.DocRoot"]}/img/${s.to_media_audio[0]["big_icon"]}">
+                            src="${config["Producer.DocRoot"]}/img/${sorig.to_media_audio[0]["big_icon"]}">
                         </if>
-                        <if s.to_media_video >
+                        <if sorig.to_media_video >
                           <img align="left" vspace="4" hspace="8"
-                            src="${config["Producer.DocRoot"]}/img/${s.to_media_video[0]["big_icon"]}">
+                            src="${config["Producer.DocRoot"]}/img/${sorig.to_media_video[0]["big_icon"]}">
                         </if>
-                        <if s.to_media_other >
+                        <if sorig.to_media_other >
                           <img align="left" vspace="4" hspace="8"
-                             src="${config["Producer.DocRoot"]}/img/${s.to_media_other[0]["big_icon"]}">
+                             src="${config["Producer.DocRoot"]}/img/${sorig.to_media_other[0]["big_icon"]}">
                         </if>
-                        <if s.to_media_images >
+                        <if sorig.to_media_images >
                           <img align="left" vspace="4" hspace="8"
-                            src="${s.to_media_images[0]["icon_path"]}"
-                            width="${s.to_media_images[0]["icon_width"]}"
-                            height="${s.to_media_images[0]["icon_height"]}"
-                            border=0 alt="${s.to_media_images[0]["title"]}">
+                            src="${sorig.to_media_images[0]["icon_path"]}"
+                            width="${sorig.to_media_images[0]["icon_width"]}"
+                            height="${sorig.to_media_images[0]["icon_height"]}"
+                            border=0 alt="${sorig.to_media_images[0]["title"]}">
                         </if>
                         ${s.description_parsed}
                     <br clear="all">
               <!--- /topic-special --->
 
               <!--- articles ---> <comment></comment>
-                <list articles as i>
+                <list articles as a>
+                 <assign aorig=a.to_original>
+               <if languagepreference>
+                 <assign i=a.to_translation(languagepreference)>
+               <else>
+                 <assign i=a>
+               </if>
+
                   <p><font size="+1">
                   <a href="${config["Producer.DocRoot"]}/${language.code}/${i.date.formatted["yyyy'/'MM"]}/${i.id}.shtml"><b>${i.title}</b></a>
                   </font><br>
-                     <font size="-2">${i.creator}, ${i.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p>
+                     <font size="-2">${aorig.creator} <if aorig.id!=i.id>(${lang("general.translatedby", i.creator)})</if><if i.creator || aorig.creator>, </if> ${aorig.creationdate.formatted["dd-MM-yyyy - HH:mm"]}</font></p>
                   <p><font size="-1">
-                  <if i.to_media_audio >
+                  <if aorig.to_media_audio >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_audio[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_audio[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_video >
+                  <if aorig.to_media_video >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_video[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_video[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_other >
+                  <if aorig.to_media_other >
                   <img align="left" vspace="4" hspace="8"
-                       src="${config["Producer.DocRoot"]}/img/${i.to_media_other[0]["big_icon"]}">
+                       src="${config["Producer.DocRoot"]}/img/${aorig.to_media_other[0]["big_icon"]}">
                   </if>
-                  <if i.to_media_images >
+                  <if aorig.to_media_images >
                   <img align="left" vspace="4" hspace="8"
-                       src="${i.to_media_images[0]["icon_path"]}"
-                       width="${i.to_media_images[0]["icon_width"]}"
-                       height="${i.to_media_images[0]["icon_height"]}"
-                       border=0 alt="${i.to_media_images[0]["title"]}">
+                       src="${aorig.to_media_images[0]["icon_path"]}"
+                       width="${aorig.to_media_images[0]["icon_width"]}"
+                       height="${aorig.to_media_images[0]["icon_height"]}"
+                       border=0 alt="${aorig.to_media_images[0]["title"]}">
                   </if>
                   ${i.description_parsed}
                   <br clear="all">
diff --git a/etc/scripts/bundletool.sh b/etc/scripts/bundletool.sh
new file mode 100755 (executable)
index 0000000..88b0d51
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+HOME=`dirname $0`
+
+for j in $HOME/../../bin/mir/WEB-INF/lib/*.jar; do
+  if [ "$CLASSPATH" ] ; then
+    CLASSPATH="$CLASSPATH:$j"
+  else
+    CLASSPATH="$j"
+  fi
+done
+export CLASSPATH
+
+if [ "$JAVA_HOME" ] ; then
+  if [ -z "$JAVACMD" ]; then
+    JAVACMD="$JAVA_HOME/bin/java"
+  fi
+fi
+
+$JAVACMD tool.BundleTool  $*
diff --git a/etc/scripts/produce.sh b/etc/scripts/produce.sh
new file mode 100755 (executable)
index 0000000..535c289
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo -e "http://your.mir.home/yourmirwebapp/servlet/Mir?login=youruser&password=yourpassword&module=Producer&do=produce&producer=$1&verb=$2\n-accept_all_cookies\n-dump" | lynx -
diff --git a/etc/scripts/reload.sh b/etc/scripts/reload.sh
new file mode 100755 (executable)
index 0000000..2737590
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo -e "http://your.mir.home/yourmirwebapp/servlet/Mir?login=youruser&password=yourpassword&module=Admin&do=reload\n-accept_all_cookies \n-dump" | lynx -
diff --git a/etc/server.xml b/etc/server.xml
deleted file mode 100755 (executable)
index 61eabc2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<!-- Example Mir Configuration File -->
- <mir name="t">
-  <class name="mircoders.servlet.ServletModuleOpenIndy">
-    <property name="directOp" value="yes"/>
-  </class>
-  <class name="mir.storage.DatabaseConfig">
-      <property name="username" value="postgres"/>
-      <property name="password" value=""/>
-  </class>
-</mir>
diff --git a/etc/web.xml b/etc/web.xml
deleted file mode 100755 (executable)
index 42b5798..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-
-<!DOCTYPE web-app
-    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
-    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
-
-<web-app>
-    <servlet>
-        <servlet-name>
-            Mir
-        </servlet-name>
-        <servlet-class>
-            Mir
-        </servlet-class>
-
-        <init-param>
-            <param-name>Config</param-name>
-            <param-value>etc/config.properties</param-value>
-        </init-param>
-
-    </servlet>
-
-    <servlet>
-        <servlet-name>
-            OpenMir
-        </servlet-name>
-        <servlet-class>
-            OpenMir
-        </servlet-class>
-
-        <init-param>
-            <param-name>Config</param-name>
-            <param-value>etc/config.properties</param-value>
-        </init-param>
-
-    </servlet>
-    
-    <servlet-mapping>
-        <servlet-name>
-            Mir
-        </servlet-name>
-        <url-pattern>
-            /Mir
-        </url-pattern>
-    </servlet-mapping>
-
-    <servlet-mapping>
-        <servlet-name>
-            Mir
-        </servlet-name>
-        <url-pattern>
-            /servlet/Mir
-        </url-pattern>
-    </servlet-mapping>
-
-    <servlet-mapping>
-        <servlet-name>OpenMir</servlet-name>
-        <url-pattern>/OpenMir</url-pattern>
-    </servlet-mapping>
-    <servlet-mapping>
-        <servlet-name>OpenMir</servlet-name>
-        <url-pattern>/servlet/OpenMir</url-pattern>
-    </servlet-mapping>
-
-    <mime-mapping>
-      <extension>
-        mp3 
-      </extension>
-      <mime-type>
-        audio/x-mp3
-      </mime-type>
-    </mime-mapping>
-    <mime-mapping>
-      <extension>
-        ra
-      </extension>
-      <mime-type>
-        audio/vnd.rn-realaudio
-      </mime-type>
-    </mime-mapping>
-    <mime-mapping>
-      <extension>
-        rm
-      </extension>
-      <mime-type>
-        application/vnd.rn-realmedia
-      </mime-type>
-    </mime-mapping>
-    <mime-mapping>
-      <extension>
-        mov
-      </extension>
-      <mime-type>
-        video/quicktime 
-      </mime-type>
-    </mime-mapping>
-    <mime-mapping>
-      <extension>
-        mpg
-      </extension>
-      <mime-type>
-        video/mpeg
-      </mime-type>
-    </mime-mapping>
-    <mime-mapping>
-      <extension>
-        avi
-      </extension>
-      <mime-type>
-        video/x-msvideo
-      </mime-type>
-    </mime-mapping>
-    <mime-mapping>
-      <extension>
-        asf
-      </extension>
-      <mime-type>
-        video/x-ms-asf
-      </mime-type>
-    </mime-mapping>
-    <mime-mapping>
-      <extension>
-        pdf
-      </extension>
-      <mime-type>
-        application/pdf
-      </mime-type>
-    </mime-mapping>
-
-    <security-constraint>
-      <web-resource-collection>
-         <web-resource-name>Protected Area</web-resource-name>
-        <!-- Define the context-relative URL(s) to be protected -->
-         <url-pattern>/jsp/security/protected/*</url-pattern>
-        <!-- If you list http methods, only those methods are protected -->
-        <http-method>DELETE</http-method>
-         <http-method>GET</http-method>
-         <http-method>POST</http-method>
-        <http-method>PUT</http-method>
-      </web-resource-collection>
-      <auth-constraint>
-         <!-- Anyone with one of the listed roles may access this area -->
-         <role-name>tomcat</role-name>
-        <role-name>role1</role-name>
-      </auth-constraint>
-    </security-constraint>
-
-    <!-- Default login configuration uses BASIC authentication -->
-    <!--
-    <login-config>
-      <auth-method>BASIC</auth-method>
-      <realm-name>Example Basic Authentication Area</realm-name>
-    </login-config>
-    -->
-
-    <!-- Form-based login is enabled by default.  If you wish to
-         try Basic authentication, comment out the <login-config>
-         section below and uncomment the one above. -->
-    <login-config>
-      <auth-method>FORM</auth-method>
-      <realm-name>Example Form-Based Authentication Area</realm-name>
-      <form-login-config>
-        <form-login-page>/jsp/security/login/login.jsp</form-login-page>
-        <form-error-page>/jsp/security/login/error.jsp</form-error-page>
-      </form-login-config>
-    </login-config>
-
-</web-app>
index a49f9bf..355c89f 100755 (executable)
@@ -155,36 +155,26 @@ url        : http://www.tfh-berlin.de/~knabe/java/multex
 description: nested exceptions
 todo       : rename to multex-3.jar
 
-
-poolman
-------------------------------------------------
-version    : ??
-url        : https://sourceforge.net/projects/poolman
-url        : http://www.codestudio.com/
-description: PoolMan is no longer available or supported 
-             Connection and object pooling mechanisms: 
-             they can now be found in application servers [...] 
-             Tomcat and the Jakarta Project, and other 
-             J2EE products and servers.
-todo       : find replacement
-
-
 postgresql
 ------------------------------------------------
-version    : 7.2 (jdbc2-version)
+version    : 7.4 (jdbc2-version)
 url        : http://jdbc.postgresql.org
 description: JDBC driver for postgresql database
 
-
-strutsmesg
-------------------------------------------------
-version    : ??
-url        : 
-description: Extracted from struts 1.0
-todo       : update
-
 velocity
 ------------------------------------------------
 version    : 1.3.1 
 url        : http://jakarta.apache.org/velocity
 description: template engine
+
+commons-pool-1.1
+------------------------------------------------
+version    : 1.1
+url        : http://jakarta.apache.org/commons-pool
+description: generic object pooling framework
+
+commons-dbcp-1.1
+-----------------------------------------------
+version    : 1.1
+url        : http://jakarta.apache.org/commons-dbcp
+description: database connection pooling library
diff --git a/lib/commons-dbcp-1.1.jar b/lib/commons-dbcp-1.1.jar
new file mode 100755 (executable)
index 0000000..c3c4d1f
Binary files /dev/null and b/lib/commons-dbcp-1.1.jar differ
diff --git a/lib/commons-fileupload-1.0-beta-1.jar b/lib/commons-fileupload-1.0-beta-1.jar
deleted file mode 100755 (executable)
index ab99356..0000000
Binary files a/lib/commons-fileupload-1.0-beta-1.jar and /dev/null differ
diff --git a/lib/commons-fileupload-1.0.jar b/lib/commons-fileupload-1.0.jar
new file mode 100755 (executable)
index 0000000..1ca4a9c
Binary files /dev/null and b/lib/commons-fileupload-1.0.jar differ
diff --git a/lib/commons-httpclient-2.0.jar b/lib/commons-httpclient-2.0.jar
new file mode 100755 (executable)
index 0000000..f58ec95
Binary files /dev/null and b/lib/commons-httpclient-2.0.jar differ
diff --git a/lib/commons-pool-1.1.jar b/lib/commons-pool-1.1.jar
new file mode 100755 (executable)
index 0000000..c61bde6
Binary files /dev/null and b/lib/commons-pool-1.1.jar differ
diff --git a/lib/poolman.jar b/lib/poolman.jar
deleted file mode 100755 (executable)
index d3de5b5..0000000
Binary files a/lib/poolman.jar and /dev/null differ
diff --git a/lib/postgresql-72jdbc2.jar b/lib/postgresql-72jdbc2.jar
deleted file mode 100755 (executable)
index 128c2d0..0000000
Binary files a/lib/postgresql-72jdbc2.jar and /dev/null differ
diff --git a/lib/postgresql-74jdbc2.jar b/lib/postgresql-74jdbc2.jar
new file mode 100755 (executable)
index 0000000..e7c2da7
Binary files /dev/null and b/lib/postgresql-74jdbc2.jar differ
diff --git a/lib/strutsmesg.jar b/lib/strutsmesg.jar
deleted file mode 100755 (executable)
index 5aeec60..0000000
Binary files a/lib/strutsmesg.jar and /dev/null differ
diff --git a/lib/xmlrpc-1.2-b1.jar b/lib/xmlrpc-1.2-b1.jar
new file mode 100755 (executable)
index 0000000..cc67714
Binary files /dev/null and b/lib/xmlrpc-1.2-b1.jar differ
diff --git a/meta/web.xml b/meta/web.xml
new file mode 100755 (executable)
index 0000000..595c304
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
+    "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
+
+<web-app>
+    <servlet>
+        <servlet-name>
+            Mir
+        </servlet-name>
+        <servlet-class>
+            Mir
+        </servlet-class>
+
+        <init-param>
+            <param-name>Config</param-name>
+            <param-value>etc/config.properties</param-value>
+        </init-param>
+
+    </servlet>
+
+    <servlet>
+        <servlet-name>
+            OpenMir
+        </servlet-name>
+        <servlet-class>
+            OpenMir
+        </servlet-class>
+
+        <init-param>
+            <param-name>Config</param-name>
+            <param-value>etc/config.properties</param-value>
+        </init-param>
+
+    </servlet>
+    
+    <servlet-mapping>
+        <servlet-name>
+            Mir
+        </servlet-name>
+        <url-pattern>
+            /Mir
+        </url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>
+            Mir
+        </servlet-name>
+        <url-pattern>
+            /servlet/Mir
+        </url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>OpenMir</servlet-name>
+        <url-pattern>/OpenMir</url-pattern>
+    </servlet-mapping>
+    <servlet-mapping>
+        <servlet-name>OpenMir</servlet-name>
+        <url-pattern>/servlet/OpenMir</url-pattern>
+    </servlet-mapping>
+
+    <mime-mapping>
+      <extension>
+        mp3 
+      </extension>
+      <mime-type>
+        audio/x-mp3
+      </mime-type>
+    </mime-mapping>
+    <mime-mapping>
+      <extension>
+        ra
+      </extension>
+      <mime-type>
+        audio/vnd.rn-realaudio
+      </mime-type>
+    </mime-mapping>
+    <mime-mapping>
+      <extension>
+        rm
+      </extension>
+      <mime-type>
+        application/vnd.rn-realmedia
+      </mime-type>
+    </mime-mapping>
+    <mime-mapping>
+      <extension>
+        mov
+      </extension>
+      <mime-type>
+        video/quicktime 
+      </mime-type>
+    </mime-mapping>
+    <mime-mapping>
+      <extension>
+        mpg
+      </extension>
+      <mime-type>
+        video/mpeg
+      </mime-type>
+    </mime-mapping>
+    <mime-mapping>
+      <extension>
+        avi
+      </extension>
+      <mime-type>
+        video/x-msvideo
+      </mime-type>
+    </mime-mapping>
+    <mime-mapping>
+      <extension>
+        asf
+      </extension>
+      <mime-type>
+        video/x-ms-asf
+      </mime-type>
+    </mime-mapping>
+    <mime-mapping>
+      <extension>
+        pdf
+      </extension>
+      <mime-type>
+        application/pdf
+      </mime-type>
+    </mime-mapping>
+</web-app>
index 83cbdaf..ae9f312 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 # Where the installed system resides
-INSTDIR=bin/mir
+INSTDIR=`dirname $0`/bin/mir
 
 # The group all files belong to
 GROUP=www-data
diff --git a/scripts/produce.sh b/scripts/produce.sh
deleted file mode 100755 (executable)
index 50d2c47..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-echo -e "http://admin.subtv.org/subtv/servlet/Mir?login=mir&password=mitmirnicht22&module=Producer&do=produce&producer=$1&verb=$2\n-accept_all_cookies\n-dump" | lynx -
diff --git a/scripts/search.pl b/scripts/search.pl
deleted file mode 100755 (executable)
index 02f1ad1..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/perl
-
-use CGI qw(:standard);
-use LWP::UserAgent;
-use URI::Escape;
-
-#this program takes, as CGI params, a query string "words"
-#a syntax string "bool" (and|or), values of Y or N for the 
-#variables of the form hasVideo, hasAudio, hasImage, etc.
-#and a variable topic corresponding to the desired topic title
-#it then munges these variables into an appropriate request to htdig,
-# does this request and forwards the results to the user 
-
-$searchhost='http://prod.indymedia.nl/cgi-bin/htsearch';
-
-$bool=param('bool');
-$hasVideo=param('hasVideo');
-$hasAudio=param('hasAudio');
-$hasImages=param('hasImages');
-$topic=param('topic');
-@topic_words=split(/\s+/,$topic);
-@words=();
-
-$querywords='';
-@words=split (/\s+/,param('words')) if param('words');
-push @words,@topic_words;
-if (@words){
-
-if ($bool eq "and"){
-$querywords=join " AND ", @words;  
-}
-else{
-$querywords=join " OR ", @words;  
-}
-
-$querywords =~ s/\(\)/ /g;
-$querywords="($querywords)";
-}
-
-if ($hasVideo eq "Y" || $hasAudio eq "Y" || $hasImages eq "Y"){
-    $first=1;
-    if (@words){
-    $querywords.=" AND ";
-}
-    $querywords .= "(";
-
-if ($hasVideo eq "Y"){
-    if (!$first){
-       $querywords.=" OR";
-    }
-    $querywords.=" RealVideo OR Video"; 
-    $first=0;
-} 
-
-if ($hasAudio eq "Y"){
-    if (!$first){
-       $querywords.=" OR";
-    }    
-    $querywords.=" RealAudio OR Audio"; 
-    $first=0;
-} 
-
-if ($hasImages eq "Y"){
-    if (!$first){
-       $querywords.=" OR";
-    }
-    $querywords.=" ImagesGif OR ImagesJpeg";
-    $first=0;
-}
-       $querywords.=" )";
-}
-
-$querywords=uri_escape($querywords,"^A-Za-z0-9");
-
-$query="words=$querywords&format=builtin-long&sort=score&method=boolean";
-
-# propagate the config parameter if it is set - rob
-$config=param('config');
-$query.="&config=$config" if $config;
-
-
-
-$ua = new LWP::UserAgent;
-$ua->agent("AgentName/0.1 " . $ua->agent);
-
-# Create a request
-my $req = new HTTP::Request POST => $searchhost;
-$req->content_type('application/x-www-form-urlencoded');
-$req->content($query);
-
-# Pass request to the user agent and get a response back
-my $res = $ua->request($req);
-
-# Check the outcome of the response
-if ($res->is_success) {
-    print header;
-    print $res->content;
-} else {
-    print header;
-    print "Search engine temporarily unavailable\n";
-}
index d367342..91be32d 100755 (executable)
  * If you do not wish to do so, delete this exception statement from your version.
  */
 
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Vector;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.UnavailableException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionBindingListener;
-
+import mir.bundle.Bundle;
 import mir.config.MirPropertiesConfiguration;
-import mir.servlet.AbstractServlet;
-import mir.servlet.ServletModule;
-import mir.servlet.ServletModuleDispatch;
-import mir.servlet.ServletModuleExc;
-import mir.servlet.ServletModuleUserExc;
+import mir.servlet.*;
 import mir.util.ExceptionFunctions;
 import mir.util.StringRoutines;
+import mir.log.LoggerWrapper;
 import mircoders.entity.EntityUsers;
 import mircoders.global.MirGlobal;
 import mircoders.module.ModuleUsers;
 import mircoders.servlet.ServletHelper;
-import mircoders.storage.DatabaseUsers;
-
-import org.apache.struts.util.MessageResources;
-
 
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.*;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Method;
+import java.util.*;
 
+import multex.Failure;
 
 /**
  * Mir.java - main servlet, that dispatches to servletmodules
- *
- * @author $Author: zapata $
- * @version $Id: Mir.java,v 1.49.2.11 2004/01/18 17:30:56 zapata Exp $
- *
  */
 public class Mir extends AbstractServlet {
   private static ModuleUsers usersModule = null;
@@ -80,29 +60,29 @@ public class Mir extends AbstractServlet {
 
   private static List loginLanguages = null;
 
-  protected List getLoginLanguages() throws ServletException {
+  private List getLoginLanguages() throws Failure {
     synchronized (Mir.class) {
       try {
         if (loginLanguages == null) {
-          MessageResources messageResources =
-            MessageResources.getMessageResources("bundles.adminlocal");
-          MessageResources messageResources2 =
-            MessageResources.getMessageResources("bundles.admin");
-
           List languages =
             StringRoutines.splitString(MirGlobal.config().getString("Mir.Login.Languages", "en"), ";");
 
-          loginLanguages = new Vector();
+          loginLanguages = new ArrayList();
 
           Iterator i = languages.iterator();
 
           while (i.hasNext()) {
             String code = (String) i.next();
-            Locale locale = new Locale(code, "");
-            String name = messageResources.getMessage(locale, "languagename");
+
+            Bundle bundle =
+                MirGlobal.getBundleFactory().getBundle("etc/bundles/adminlocal", new String[] { code });
+            Bundle defaultBundle =
+                MirGlobal.getBundleFactory().getBundle("bundles/admin", new String[] { code });
+
+            String name = bundle.getValue("languagename", Collections.EMPTY_LIST);
 
             if (name == null) {
-              name = messageResources2.getMessage(locale, "languagename");
+              name = defaultBundle.getValue("languagename", Collections.EMPTY_LIST);
             }
 
             if (name == null) {
@@ -119,7 +99,7 @@ public class Mir extends AbstractServlet {
         return loginLanguages;
       }
       catch (Throwable t) {
-        throw new ServletException(t.getMessage());
+        throw new Failure("Error while retrieving the available login languages", t);
       }
     }
   }
@@ -127,7 +107,7 @@ public class Mir extends AbstractServlet {
   public void init(ServletConfig config) throws ServletException {
     super.init(config);
 
-    usersModule = new ModuleUsers(DatabaseUsers.getInstance());
+    usersModule = new ModuleUsers();
   }
 
   protected String getDefaultLanguage(HttpServletRequest aRequest) {
@@ -253,7 +233,7 @@ public class Mir extends AbstractServlet {
       }
     }
     catch (Throwable t) {
-      t.printStackTrace();
+      t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
 
       throw new ServletException(t.toString());
     }
@@ -308,8 +288,21 @@ public class Mir extends AbstractServlet {
 
       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale()});
 
-      MessageResources messages = MessageResources.getMessageResources("bundles.admin");
-      responseData.put("errorstring", messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters()));
+      Bundle bundle =
+          MirGlobal.getBundleFactory().getBundle("etc/bundles/adminlocal", new
+              String[] { getLocale(aRequest).getLanguage() });
+      Bundle defaultBundle =
+          MirGlobal.getBundleFactory().getBundle("bundles/admin", new
+              String[] { getLocale(aRequest).getLanguage() });
+      String message =
+        bundle.getValue(anException.getMessage(), Arrays.asList(anException.getParameters()));
+
+      if (message==null) {
+        message =
+          defaultBundle.getValue(anException.getMessage(), Arrays.asList(anException.getParameters()));
+      }
+
+      responseData.put("errorstring", message);
       responseData.put("date", new GregorianCalendar().getTime());
 
       ServletHelper.generateResponse(aResponse.getWriter(), responseData, MirPropertiesConfiguration.instance().getString("Mir.UserErrorTemplate"));
@@ -332,6 +325,22 @@ public class Mir extends AbstractServlet {
     }
     catch (Throwable e) {
       logger.error("Error handling error: " + e.toString());
+
+      try {
+        Throwable rootException = ExceptionFunctions.traceCauseException(anException);
+
+        PrintWriter writer = aResponse.getWriter();
+        writer.println("<html><head><title>FATAL Error</title><body>");
+        writer.println("<h1>" + rootException.toString()+"</h1>");
+        writer.println("<code>");
+        rootException.printStackTrace(writer);
+        writer.println("</code>");
+        writer.println("</body></html>");
+        writer.close();
+      }
+      catch (Throwable t) {
+
+      }
     }
   }
 
index 1daa016..dfdbe4d 100755 (executable)
@@ -46,7 +46,7 @@ import mircoders.servlet.ServletModuleOpenIndy;
  *  OpenMir.java - main servlet for open posting and comment feature to articles
  *
  *  @author RK 1999-2001, the mir-coders group
- *  @version $Id: OpenMir.java,v 1.35.2.2 2003/10/23 14:55:26 rk Exp $
+ *  @version $Id: OpenMir.java,v 1.35.2.3 2004/11/21 22:07:13 zapata Exp $
  *
  */
 
@@ -54,15 +54,14 @@ import mircoders.servlet.ServletModuleOpenIndy;
 public class OpenMir extends AbstractServlet {
   public void process(HttpServletRequest aRequest, HttpServletResponse aResponse)
         throws ServletException, IOException {
-                if ((configuration.getString("RootUri") == null) ||
-                        configuration.getString("RootUri").equals("")) {
-                  configuration.setProperty("RootUri", aRequest.getContextPath());
-                }
+    if ((configuration.getString("RootUri") == null) ||
+        configuration.getString("RootUri").equals("")) {
+      configuration.setProperty("RootUri", aRequest.getContextPath());
+    }
 
     long startTime = System.currentTimeMillis();
     long sessionConnectTime=0;
 
-
     HttpSession session = aRequest.getSession();
 
     checkLanguage(session, aRequest);
index 15136d9..970cf9a 100755 (executable)
@@ -1,35 +1,4 @@
 #
-# Sample config for Mir
-# by Matthias <mjordan@code-fu.de> 2001-09-12
-#
-# The Mir software realizes a semi-dynamic web service:
-# The web server that is accessed by users has pure static
-# pages. These pages are generated by the Mir software that
-# consists of a collection of Java servlets and HTML templates.
-# Mir uses a database server to store the data that is needed to
-# build the static site.
-# So there are basically three parts in this config file:
-#
-# a) general setup
-# b) static site config
-# c) dynamic admin site
-# d) database config
-#
-# edit this to suit your needs (here with sampleuser idfx)
-# After you edited this file, build.sh has to be invoked.
-# To be sure, also restart Tomcat.
-#
-# Note that for Mir to work, Tomcat has to be set up to handle all
-# URLs that begin with /servlet. All other URLs are handled by Apache.
-#
-# The setup uses the following assumptions:
-# The URL to reach the site is http://indy.code-fu.de
-# The StorageRoot of this URL is /pub/Dokumente/Indymedia/de-tech/Mir
-# All data is located below this directory, including the servlets.
-
-
-#
-#
 # GENERAL SETUP
 #
 
@@ -43,7 +12,7 @@ Mir.Tech-email.name=mir-coders mailinglist
 Mir.Public-email.address=mir-coders@lists.indymedia.org
 Mir.Public-email.name=mir-coders mailinglist
 
-Mir.Version=1.1beta
+Mir.Version=1.1.0rc0
 DirectOpenposting=yes
 
 # The name of the abuse config file (relative to the WEB-INF dir)
@@ -61,7 +30,7 @@ Abuse.CookieMaxAge=168
 
 
 #where to put the lucene index
-IndexPath=/tmp/index
+IndexPath=index
 
 TempDir=/tmp
 
@@ -91,27 +60,33 @@ Mir.Admin.ShowLoggedinUsers=1
 # Log admin activity?
 Mir.Admin.LogAdminActivity=0
 
+# Limit the length of text shown in lists (-1 means no limit)
+Mir.Admin.ListTextLengthLimit=-1
+
 # Which usernames have admin priviliges (, seperated usernames)
 AccessControl.SuperUsers = admin
 
 # Locking enabled?
 AccessControl.LockingEnabled = 0
 
-# If locking enabled, should users lock articles before they 
+# If locking enabled, should users lock articles before they
 #    can edit?
 AccessControl.LockingOptional = 1
 
 # the templates
 Mir.Localizer.Producer.GeneratorLibrary= default=freemarker(etc/producer/)
-Mir.Localizer.Admin.GeneratorLibrary= default=freemarker(templates/admin/)
+Mir.Localizer.Admin.GeneratorLibrary= default=freemarker(templates/admin/),preview=freemarker(etc/producer)
 Mir.Localizer.OpenPosting.GeneratorLibrary= default=freemarker(etc/open/)
 
 # How should the custom operations (hide etc) in article and comment lists
 # be presented?
 # 0 = links, 1 = checkboxes, 2 = a listbox
-Mir.Localizer.Admin.ListOperationsFlavor=1
-
-
+Mir.Localizer.Admin.ListOperationsFlavor=2
+                            
+# Article previews, a comma seperated list of name = generator
+Mir.Localizer.Admin.ArticlePreview = \
+  default = preview::article.template
+Mir.Localizer.Admin.ArticlePreviewLanguage=en
 
 # How should the topics be presented on the article edit page?
 #
@@ -149,7 +124,7 @@ Mir.Localizer.OpenPosting.ContentProducers= media.new;articles.changed;startpage
 Mir.Localizer.OpenPosting.CommentProducers= articles.changed;synchronization.run
 
 # Which producers need to be called after the "produce all new" link is clicked from admin
-Mir.Localizer.Producer.ProducerRecipes= 
+Mir.Localizer.Producer.ProducerRecipes= \
   allnew = media.new;articles.changed;startpage.run;synchronization.run
 
 
@@ -184,7 +159,7 @@ Producer.StorageRoot=/pub/Dokumente/Indymedia/de-tech/Mir/produced
 
 # FileEdit module
 #   a list of directories to edit
-#   format: 
+#   format:
 #      <name>:<path>:<file filter>:<0|1 (recursion off or on)> [, ....]
 
 ServletModule.FileEdit.Configuration= \
@@ -274,11 +249,11 @@ Producer.Icon.BigText=text_big.gif
 Producer.HTML2FOStyleSheet=/some/dir/mir/etc/producer/html2fo.xsl
 
 # the following lines are used to construct PDFs on the fly from one or more articles
-# for the moment, if you want to change anything else about your pdfs, you 
+# for the moment, if you want to change anything else about your pdfs, you
 # will have to learn some java!
 #
-# keep in mind that there may not be enough room for all the text you enter as the 
-# value of one these options, if text doesn't appear, the only easy thing to do is 
+# keep in mind that there may not be enough room for all the text you enter as the
+# value of one these options, if text doesn't appear, the only easy thing to do is
 # use less text!
 #
 # also, be sure to adjust the corresponding line height if you change a font size...
@@ -304,12 +279,12 @@ PDF.Title.FontSize=24
 PDF.Title.LineHeight=28
 PDF.Title.FontFamily=courier
 
-# footer is about two lines of small text which will appear at the bottom of every page 
+# footer is about two lines of small text which will appear at the bottom of every page
 
 PDF.Footer.String=Indymedia does blah.  Content is good, and free to use for non-commercial purposes under the Open Content license. if you have questions, email someone.
 PDF.Footer.Height=54
 PDF.Footer.FontSize=12
-PDF.Footer.FontFamily=helvetica 
+PDF.Footer.FontFamily=helvetica
 
 # how to format the index, i.e. the newsletter table of contents
 
@@ -321,7 +296,7 @@ PDF.Index.FontFamily=helvetica
 
 PDF.Meta.Height=36
 PDF.Meta.FontSize=14
-PDF.Meta.FontFamily=helvetica 
+PDF.Meta.FontFamily=helvetica
 RDF.Meta.DateFormat=yyyy-MM-dd HH:mm
 
 # how to format the article description
@@ -403,8 +378,23 @@ Mir.DefaultTimezone= UTC
 # Default date/time format
 Mir.DefaultDateTimeFormat = yyyy-MM-dd HH:mm
 
+# Compatibility feature: updated posting forms can
+# support persistent uploads (that is, uploads remainig
+# valid after validation errors). To support existing
+# forms, by default it is off.
+Localizer.OpenSession.PersistentUploadedFiles = 0
 
+# Should support for ftp-like uploads (uploads done
+# outside of mir, but included into postings) be 
+# supported at all?
+Localizer.OpenSession.AllowFTPUploads = 0
 
+# When uploading ftp files, should a list of available
+# files be displayed?
+Localizer.OpenSession.AllowFTPUploadSelection = 0
+
+# What is the place where files are uploaded?
+Localizer.OpenSession.FTPDirectory = /somewhere
 
 Localizer.OpenSession.article.EditTemplate = editarticle.template
 Localizer.OpenSession.article.DupeTemplate = dupearticle.template
@@ -524,6 +514,18 @@ ServletModule.MediaType.DeleteConfirmationTemplate=confirm.template
 ServletModule.MediaType.EditTemplate=mediatype.template
 ServletModule.MediaType.ListTemplate=mediatypelist.template
 
+#
+# Object store configuration
+#
+
+StoreContainer.EntityDefaultSize= 45
+StoreContainer.EntityListDefaultSize= 15
+StorableObjectEntity.Entity.DefaultSize= 300
+StorableObjectEntity.EntityList.DefaultSize= 100
+EntityTopics.Entity.DefaultSize=              200
+EntityTopics.EntityList.DefaultSize=          20
+
+
 
 
 
@@ -543,3 +545,6 @@ Producer.ExtLinkName=extlink.gif
 Producer.IntLinkName=intlink.gif
 Producer.MailLinkName=maillink.gif
 
+# should the <Bundle producer tag be backwards compatible
+# (this means that old bundle paths get mapped to new ones)
+Producer.BundleCompatibility=1
diff --git a/source/mir/bundle/BasicBundleFactory.java b/source/mir/bundle/BasicBundleFactory.java
new file mode 100755 (executable)
index 0000000..ac9aeb9
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.bundle;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The <code>BasicBundleFactory</code> is responsible for managing
+ * loaded bundles. It caches previously retrieved bundles to improve
+ * performance.
+ */
+public class BasicBundleFactory implements BundleFactory {
+  private Map directories;
+  private BundleLoader loader;
+
+  public BasicBundleFactory(BundleLoader aLoader) {
+    directories = new HashMap();
+    loader = aLoader;
+  }
+
+  private Map getBundleDirectory(String aDirectory) {
+    synchronized (directories) {
+      Map result = (Map) directories.get(aDirectory);
+
+      if (result == null) {
+        result = new HashMap();
+        directories.put(aDirectory, result);
+      }
+
+      return result;
+    }
+  }
+
+  private Bundle loadBundle(String aDirectory, String[] aParameters) {
+    return loader.loadBundle(aDirectory, aParameters);
+  }
+
+  public Bundle getBundle(String aDirectory, String[] aParameters) {
+    Map directory = getBundleDirectory(aDirectory);
+    List parameters = java.util.Arrays.asList(aParameters);
+
+    Bundle result = (Bundle) directory.get(parameters);
+
+    if (result==null) {
+      result = loadBundle(aDirectory, aParameters);
+      directory.put(parameters, result);
+    }
+
+    return result;
+  }
+
+  public void reload() {
+    synchronized (directories) {
+      directories.clear();
+    }
+  }
+}
diff --git a/source/mir/bundle/Bundle.java b/source/mir/bundle/Bundle.java
new file mode 100755 (executable)
index 0000000..cec44e4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.bundle;
+
+import java.util.List;
+
+public interface Bundle {
+  public String getValue(String aKey, List anArguments);
+}
diff --git a/source/mir/bundle/BundleFactory.java b/source/mir/bundle/BundleFactory.java
new file mode 100755 (executable)
index 0000000..7df1476
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.bundle;
+
+public interface BundleFactory {
+  /**
+   * Retrieves a bundle
+   */
+  public Bundle getBundle(String aDirectory, String[] aParameters);
+
+  /**
+   * Invalidates the bundle cache
+   */
+  public void reload();
+}
diff --git a/source/mir/bundle/BundleLoader.java b/source/mir/bundle/BundleLoader.java
new file mode 100755 (executable)
index 0000000..7674e94
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.bundle;
+
+/**
+ * <p>
+ * The BundleLoader is responsible for the physical loading of (abstract)
+ * {@link Bundle}s. A <code>Bundle</code> is identified by a directory
+ * and a set of parameters. The directory typically denotes the base of
+ * a set of <code>Bundles</code>, the parameters stand for a particular
+ * instance. E.g. the directory might stand for the purpose of the bundles,
+ * the parameters for the locale.
+ * </p>
+ * <p>
+ * <code>BundleLoader</code>s should not do any caching, since that's the
+ * responsibility of the {@link BasicBundleFactory}.
+ * </p>
+ */
+public interface BundleLoader {
+  /**
+   * Loads the bundle specified by <code>aDirectory</code> and
+   * <code>aParameters</code>.
+   */
+  public Bundle loadBundle(String aDirectory, String[] aParameters);
+}
diff --git a/source/mir/bundle/CascadingBundleFactory.java b/source/mir/bundle/CascadingBundleFactory.java
new file mode 100755 (executable)
index 0000000..b3a9920
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.bundle;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CascadingBundleFactory implements BundleFactory {
+  private BundleFactory masterFactory;
+
+  /** {@inheritDoc} */
+  public CascadingBundleFactory(BundleFactory aMasterFactory) {
+    masterFactory = aMasterFactory;
+  }
+
+  /** {@inheritDoc} */
+  public Bundle getBundle(final String aDirectory, final String[] aParameters) {
+    return
+      new Bundle() {
+        public String getValue(String aKey, List anArguments) {
+          String result = masterFactory.getBundle(aDirectory, aParameters).getValue(aKey, anArguments);
+
+          if (aParameters.length>0 && result==null) {
+            List parameters = new ArrayList(Arrays.asList(aParameters));
+
+            while (result==null && parameters.size()>0) {
+              parameters.remove(parameters.size()-1);
+              result = masterFactory.getBundle(
+                  aDirectory, (String[]) parameters.toArray(new String[0])).getValue(aKey, anArguments);
+            }
+          }
+
+          return result;
+        }
+      };
+  }
+
+  /** {@inheritDoc} */
+  public void reload() {
+    masterFactory.reload();
+  }
+}
diff --git a/source/mir/bundle/PropertiesBundle.java b/source/mir/bundle/PropertiesBundle.java
new file mode 100755 (executable)
index 0000000..a795285
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.bundle;
+
+import java.util.Properties;
+import java.util.List;
+import java.util.Iterator;
+
+import mir.util.StringParseRoutines;
+
+/**
+ * Bundle implementation using a {@link Properties}
+ * object.
+ */
+
+public class PropertiesBundle implements Bundle {
+  private Properties properties;
+
+  public PropertiesBundle(Properties aProperties) {
+    properties = aProperties;
+  }
+
+  private String formatValue(String anExpression, List anArguments) {
+    StringBuffer result = new StringBuffer();
+
+    List parts = StringParseRoutines.parseBracketedExpression(
+        anExpression, '\\', "{", "}" );
+
+    Iterator i = parts.iterator();
+    while (i.hasNext()) {
+      result.append(i.next());
+      if (i.hasNext()) {
+        String expression = (String) i.next();
+        try {
+          int parameterNr = Integer.parseInt(expression);
+          if (parameterNr>=0 && parameterNr<anArguments.size()) {
+            result.append(anArguments.get(parameterNr));
+          }
+        }
+        catch (Throwable t) {
+        }
+      }
+    }
+
+    return result.toString();
+  }
+
+  /** {@inheritDoc} */
+  public String getValue(String aKey, List anArguments) {
+    String result = (String) properties.get(aKey);
+
+    if (result==null || result.trim().length()==0)
+      return null;
+    else
+      return formatValue(result, anArguments);
+  }
+}
diff --git a/source/mir/bundle/PropertiesFileBundleLoader.java b/source/mir/bundle/PropertiesFileBundleLoader.java
new file mode 100755 (executable)
index 0000000..5e88976
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.bundle;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.util.Properties;
+
+/**
+ * Loads properties files relative to a base directory as {@link Bundle}s
+ */
+public class PropertiesFileBundleLoader implements BundleLoader {
+  private File baseDirectory;
+
+  /** {@inheritDoc} */
+  public PropertiesFileBundleLoader(File aBaseDirectory) {
+    baseDirectory = aBaseDirectory;
+  }
+
+  /** {@inheritDoc} */
+  public Bundle loadBundle(String aDirectory, String[] aParameters) {
+    Properties properties = new Properties();
+    String fileName = aDirectory;
+    for (int i=0; i<aParameters.length; i++) {
+      fileName = fileName + "_" + aParameters[i];
+    }
+    fileName = fileName + ".properties";
+
+    File file = new File(baseDirectory, fileName);
+
+    try {
+      properties.load(new FileInputStream(file));
+    }
+    catch (IOException e) {
+    }
+
+    return new PropertiesBundle(properties);
+  }
+}
index 2d5c038..80ece21 100755 (executable)
 package mir.config;
 
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-
 import javax.servlet.ServletContext;
 
 import multex.Exc;
 import multex.Failure;
-
 import org.apache.commons.collections.ExtendedProperties;
 
-
 /**
  * @author idefix
  */
 public class MirPropertiesConfiguration extends ExtendedProperties {
   private static MirPropertiesConfiguration instance;
   private static ServletContext context;
-  private static String contextPath;
 
-  //if one of these properties is not present a new
-  //property is added with its default value;
-  private static NeededProperty[] neededWithValue =
-  {
-    new NeededProperty("Producer.DocRoot", ""),
-    new NeededProperty("Producer.ImageRoot", ""),
-    new NeededProperty("Producer.Image.Path", ""),
-    new NeededProperty("Producer.Media.Path", ""),
-    new NeededProperty("Producer.RealMedia.Path", ""),
-    new NeededProperty("Producer.Image.IconPath", "")
-  };
+  private File home;
 
   /**
    * Constructor for MirPropertiesConfiguration.
    */
-  private MirPropertiesConfiguration(ServletContext ctx, String ctxPath)
-    throws IOException {
+  private MirPropertiesConfiguration(ServletContext ctx) throws IOException {
     //loading the defaults-config
     super(ctx.getRealPath("/WEB-INF/") + "/default.properties");
+
     //loading the user-config
     ExtendedProperties userConfig =
       new ExtendedProperties(ctx.getRealPath("/WEB-INF/etc/") + "/config.properties");
+
     //merging them to one config while overriding the defaults
     this.combine(userConfig);
-    addProperty("Home", ctx.getRealPath("/WEB-INF/") + "/");
-    checkMissing();
+
+    home = new File(ctx.getRealPath("/WEB-INF/")+"/");
   }
 
-  public static synchronized MirPropertiesConfiguration instance()
-    throws PropertiesConfigExc {
+  public static synchronized MirPropertiesConfiguration instance() {
     if (instance == null) {
       if (context == null) {
-        throw new MirPropertiesConfiguration.PropertiesConfigExc(
-          "Context was not set");
+        throw new Error("Context was not set");
       }
 
       try {
-        instance = new MirPropertiesConfiguration(context, contextPath);
+        instance = new MirPropertiesConfiguration(context);
       }
       catch (IOException e) {
-        throw new RuntimeException(e.toString());
+        throw new Error("cannot load configuration: " + e.toString());
       }
     }
 
@@ -101,6 +85,7 @@ public class MirPropertiesConfiguration extends ExtendedProperties {
 
   /**
    * Sets the context.
+   *
    * @param context The context to set
    */
   public static void setContext(ServletContext context) {
@@ -109,6 +94,7 @@ public class MirPropertiesConfiguration extends ExtendedProperties {
 
   /**
    * Returns the context.
+   *
    * @return ServletContext
    */
   public static ServletContext getContext() {
@@ -126,58 +112,51 @@ public class MirPropertiesConfiguration extends ExtendedProperties {
       String key = (String) iterator.next();
       Object o = this.getProperty(key);
 
-      if (o == null) {
-        o = new Object();
-      }
-
       returnMap.put(key, o);
     }
 
+    // ML: hack for now
+    if (!returnMap.containsKey("Producer.DocRoot")) {
+      returnMap.put("Producer.DocRoot", "");
+    }
+
     return returnMap;
   }
 
   /**
-   * Returns a String-property concatenated with the home-dir of the
-   * installation
-   * @param key
-   * @return String
+   * Return mir's home directory.
+   * Normally this is the <code>WEB-INF</code> dir of the
+   * deployed mir servlets.
    */
-  public String getStringWithHome(String key) {
-    String returnString = getString(key);
-
-    if (returnString == null) {
-      returnString = new String();
-    }
-
-    return getString("Home") + returnString;
+  public File getHome() {
+    return home;
   }
 
   /**
-   * Checks if one property is missing and adds a default value
+   * Returns a file based on a configuration setting.
+   *
+   * The file may be configured with an absolute path, or
+   * it may be a relative path.
+   *
+   * Relative paths work relative to {@link #home} :
+   * normally this is the <code>WEB-INF</code> dir in a
+   * deployed java servlet.
    */
-  private void checkMissing() {
-    for (int i = 0; i < neededWithValue.length; i++) {
-      if (super.getProperty(neededWithValue[i].getKey()) == null) {
-        addProperty(neededWithValue[i].getKey(), neededWithValue[i].getValue());
-      }
-    }
-  }
+  public File getFile(String aKey) {
+    String path = getString(aKey);
 
-  public File getFile(String key) throws FileNotFoundException {
-    String path = getStringWithHome(key);
-    File returnFile = new File(path);
-
-    if (returnFile.exists()) {
-      return returnFile;
-    } else {
-      throw new FileNotFoundException();
+    File result = new File(path);
+    if (result.isAbsolute()) {
+      return result;
+    }
+    else {
+      return new File(home, path);
     }
   }
 
   /**
    * @return the vlaue of this property as String
    * @param key the key of this property
-   * @see org.apache.commons.configuration.Configuration#getString(java.lang.String)
    */
   public String getString(String key) {
     return getString(key, "");
@@ -204,11 +183,26 @@ public class MirPropertiesConfiguration extends ExtendedProperties {
     return object.toString();
   }
 
+  public boolean getBoolean(String aKey, boolean aDefaultValue) {
+    try {
+      return getBoolean(aKey);
+    }
+    catch (Throwable t) {
+      return aDefaultValue;
+    }
+  }
+
+  public boolean getBoolean(String aKey) {
+    String value = getString(aKey).trim();
+
+    return "1".equals(value) || "y".equalsIgnoreCase(value) ||
+        "yes".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value);
+  }
+
   /**
    * Returns a property according to the given key
    * @param key the key of the property
    * @return the value of the property as Object, if no property available it returns a empty String
-   * @see org.apache.commons.configuration.Configuration#getString(java.lang.String)
    */
   public Object getProperty(String key) {
     if (super.getProperty(key) == null) {
@@ -224,7 +218,6 @@ public class MirPropertiesConfiguration extends ExtendedProperties {
   public static class PropertiesConfigExc extends Exc {
     /**
      * Constructor for PropertiesConfigExc.
-     * @param arg0
      */
     public PropertiesConfigExc(String msg) {
       super(msg);
@@ -237,32 +230,9 @@ public class MirPropertiesConfiguration extends ExtendedProperties {
   public static class PropertiesConfigFailure extends Failure {
     /**
      * Constructor for PropertiesConfigExc.
-     * @param arg0
      */
     public PropertiesConfigFailure(String msg, Throwable cause) {
       super(msg, cause);
     }
   }
-
-  /**
-   * A Class for properties to be checked
-   * @author idefix
-   */
-  private static class NeededProperty {
-    private String _key;
-    private String _value;
-
-    public NeededProperty(String key, String value) {
-      _key = key;
-      _value = value;
-    }
-
-    public String getKey() {
-      return _key;
-    }
-
-    public String getValue() {
-      return _value;
-    }
-  }
 }
index dcd493b..a4e6585 100755 (executable)
@@ -45,25 +45,16 @@ import mir.storage.StorageObjectFailure;
  * Base class the entities are derived from. Provides base functionality of
  * an entity.
  *
- * @version $Id: AbstractEntity.java,v 1.8.2.2 2004/02/08 21:05:00 zapata Exp $
+ * @version $Id: AbstractEntity.java,v 1.8.2.3 2004/11/21 22:07:13 zapata Exp $
  */
 
 public class AbstractEntity implements Entity {
-  protected static MirPropertiesConfiguration configuration;
+  protected static MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
 
   protected Map values;
   protected StorageObject storageObject;
   protected LoggerWrapper logger;
 
-  static {
-    try {
-      configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (PropertiesConfigExc e) {
-      throw new RuntimeException(e.getMessage());
-    }
-  }
-
   public AbstractEntity() {
     logger = new LoggerWrapper("Entity");
 
@@ -74,7 +65,6 @@ public class AbstractEntity implements Entity {
    * Constructor
    * @param StorageObject The StorageObject of the Entity.
    */
-
   public AbstractEntity(StorageObject StorageObject) {
     this();
 
@@ -159,7 +149,7 @@ public class AbstractEntity implements Entity {
    * Returns the field names of the Entity
    */
   public List getFieldNames() throws StorageObjectFailure {
-    return storageObject.getFields();
+    return storageObject.getFieldNames();
   }
 
   /** Returns whether fieldName is a valid field name of this Entity.
index fad20bf..a2e6cce 100755 (executable)
@@ -27,7 +27,7 @@
  * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
-package  mir.entity;
+package mir.entity;
 
 import java.util.ArrayList;
 import java.util.Set;
@@ -52,38 +52,35 @@ import mir.storage.store.StoreUtil;
  * @version 1.1 (cleaned up)
  */
 public class EntityList implements StorableObject {
-  protected static MirPropertiesConfiguration configuration;
+  protected static MirPropertiesConfiguration configuration  = MirPropertiesConfiguration.instance();
   protected LoggerWrapper logger;
   private ArrayList           theEntityArrayList = new ArrayList();
   private String              whereClause, orderClause;
-  private StorageObject       theStorage;
+  private StorageObject       storage;
   private int                 count, offset, limit;
-  private int                 offsetnext = -1, offsetprev = -1;
+  private int                 nextOffset = -1;
+  private int                 previousOffset = -1;
 
-  static {
-    try {
-      configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (PropertiesConfigExc e) {
-      throw new RuntimeException("Unable to get configuration: " + e.getMessage());
-    }
-  }
-
-  /**
-   * Constructor.
-   */
   public EntityList(){
     logger = new LoggerWrapper("Entity.List");
   }
 
 /* get/set EntityClass of Objects stored in EntityList */
-  public void setStorage(StorageObject storage) { this.theStorage=storage; }
-  public StorageObject getStorage() { return theStorage; }
+  public void setStorage(StorageObject aStorage) {
+    storage=aStorage;
+  }
 
-  public void setLimit(int limit) { this.limit = limit; }
+  public StorageObject getStorage() {
+    return storage;
+  }
+
+  public void setLimit(int aLimit) {
+    limit = aLimit;
+  }
 
   /**
    * Sets the WHERE clause that fetched the Entities of this EntityList from the database.
+   *
    * @param wc The string that contains the WHERE clause
    */
   public void setWhere(String wc) {
@@ -92,6 +89,7 @@ public class EntityList implements StorableObject {
 
   /**
    * Returns the WHERE clause that returned this EntityList from the database
+   *
    * @return whereClause The WHERE clause
    */
   public String getWhere() {
@@ -100,6 +98,7 @@ public class EntityList implements StorableObject {
 
   /**
    * Sets the sorting criterium of this EntityList
+   *
    * @param oc
    */
   public void setOrder(String oc) {
@@ -108,6 +107,7 @@ public class EntityList implements StorableObject {
 
   /**
    * Returns the sorting criterium.
+   *
    * @return orderClause The sort order
    */
   public String getOrder() {
@@ -116,14 +116,16 @@ public class EntityList implements StorableObject {
 
   /**
    * Sets the number of rows that match the WHERE clause
+   *
    * @param i The number of rows that match the WHERE clause
    */
   public void setCount(int i) {
-    this.count = i;
+    count = i;
   }
 
   /**
    * Returns the number of rows that match the WHERE clause
+   *
    * @return The number of rows ...
    */
   public int getCount() {
@@ -132,6 +134,7 @@ public class EntityList implements StorableObject {
 
   /**
    * Sets the offset
+   *
    * @param i The offset
    */
   public void setOffset(int i) {
@@ -140,6 +143,7 @@ public class EntityList implements StorableObject {
 
   /**
    * Returns the offset
+   *
    * @return offset
    */
   public int getOffset() {
@@ -148,54 +152,61 @@ public class EntityList implements StorableObject {
 
   /**
    * Sets the offset of the next batch of Entities.
+   *
    * @param i The next offset
    */
   public void setNextBatch(int i) {
-    offsetnext = i;
+    nextOffset = i;
   }
 
   /**
    * Returns the offset of the next batch of Entities.
+   *
    * @return offset of the next batch
    */
   public int getNextBatch() {
-    return offsetnext;
+    return nextOffset;
   }
 
   /**
    * Returns whether there is a next batch within the WHERE clause
+   *
    * @return true if yes, false if no.
    */
   public boolean hasNextBatch() {
-    return (offsetnext >= 0);
+    return (nextOffset >= 0);
   }
 
   /**
    * Sets the offset of the previous batch.
+   *
    * @param i the previous offset
    */
   public void setPrevBatch(int i) {
-    offsetprev = i;
+    previousOffset = i;
   }
 
   /**
    * Returns the offset of the previous batch.
+   *
    * @return offset of the previous batch
    */
   public int getPrevBatch() {
-    return offsetprev;
+    return previousOffset;
   }
 
   /**
    * Returns whether there is a previous batch.
+   *
    * @return true if yes, false if no
    */
   public boolean hasPrevBatch() {
-    return (offsetprev >= 0);
+    return (previousOffset >= 0);
   }
 
   /**
    * Returns the start index of the batch.
+   *
    * @return
    */
   public int getFrom() {
@@ -204,17 +215,19 @@ public class EntityList implements StorableObject {
 
   /**
    * Returns the end index of the batch.
+   *
    * @return
    */
   public int getTo() {
     if (hasNextBatch())
-      return offsetnext;
+      return nextOffset;
     else
       return count;
   }
 
   /**
    * Inserts an Entity into the EntityList.
+   *
    * @param anEntity The entity to be inserted.
    */
 
@@ -253,14 +266,18 @@ public class EntityList implements StorableObject {
   public Set getNotifyOnReleaseSet() { return null; }
 
   public StoreIdentifier getStoreIdentifier() {
-    if ( theStorage!=null ) {
+    if ( storage!=null ) {
       return
-      new StoreIdentifier( this, StoreContainerType.STOC_TYPE_ENTITYLIST,
-      StoreUtil.getEntityListUniqueIdentifierFor( theStorage.getTableName(),
-      whereClause, orderClause, offset, limit ));
+        new StoreIdentifier(
+                this, StoreContainerType.STOC_TYPE_ENTITYLIST,
+                StoreUtil.getEntityListUniqueIdentifierFor( storage.getTableName(),
+                whereClause, orderClause, offset, limit ));
+    }
+    else {
+      logger.warn("EntityList could not return StoreIdentifier");
+      
+      return null;
     }
-    logger.warn("EntityList could not return StoreIdentifier");
-    return null;
   }
 
 }
index 7df00ef..19f37be 100755 (executable)
@@ -30,8 +30,8 @@
 package mir.entity.adapter;
 
 import java.util.AbstractList;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Vector;
 
 import mir.entity.Entity;
 import mir.entity.EntityBrowser;
@@ -53,7 +53,7 @@ public class EntityListAdapter extends AbstractList {
     browser = aBrowser;
     skip = aSkip;
     maximumLength = aMaximumLength;
-    cache = new Vector();
+    cache = new ArrayList();
   }
 
   protected EntityListAdapter(EntityAdapterModel aModel, String aDefinition, EntityBrowser aBrowser, int aMaximumLength) {
index d1c5651..324363f 100755 (executable)
@@ -32,16 +32,16 @@ package mir.generator;
 import java.util.HashMap;
 import java.util.Map;
 
-public class CompositeGeneratorLibrary implements Generator.GeneratorLibrary {
+public class CompositeGeneratorLibrary implements Generator.Library {
   private Map generatorLibraries;
-  private Generator.GeneratorLibrary defaultLibrary = null;
+  private Generator.Library defaultLibrary = null;
   private static String LIBRARY_QUALIFIER_SEPARATOR = "::";
 
   public CompositeGeneratorLibrary() {
     generatorLibraries = new HashMap();
   }
 
-  public void addLibrary(String aQualifier, Generator.GeneratorLibrary aLibrary, boolean anIsDefault) {
+  public void addLibrary(String aQualifier, Generator.Library aLibrary, boolean anIsDefault) {
     if (anIsDefault || defaultLibrary == null) {
       defaultLibrary = aLibrary;
     }
@@ -53,14 +53,14 @@ public class CompositeGeneratorLibrary implements Generator.GeneratorLibrary {
     String qualifier;
     String libraryName;
     int position;
-    Generator.GeneratorLibrary library;
+    Generator.Library library;
 
     position = anIdentifier.indexOf( LIBRARY_QUALIFIER_SEPARATOR );
     if (position>=0) {
       libraryName = anIdentifier.substring(0, position);
       qualifier = anIdentifier.substring(position + LIBRARY_QUALIFIER_SEPARATOR.length());
 
-      library = (Generator.GeneratorLibrary) generatorLibraries.get(libraryName);
+      library = (Generator.Library) generatorLibraries.get(libraryName);
       if (library==null)
         throw new GeneratorExc("CompositeGeneratorLibrary: library '"+libraryName+"' not found");
 
index c0ebb76..d4a4ee7 100755 (executable)
 package mir.generator;
 
 import java.io.PrintWriter;
+import java.io.File;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
-
-import mir.log.LoggerWrapper;
-import mir.util.GeneratorFormatAdapters;
-import mir.util.RewindableIterator;
-
-import org.apache.commons.beanutils.MethodUtils;
-import org.apache.commons.beanutils.PropertyUtils;
 
 import freemarker.template.FileTemplateCache;
 import freemarker.template.SimpleScalar;
@@ -54,6 +48,11 @@ import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateModelRoot;
 import freemarker.template.TemplateScalarModel;
+import mir.log.LoggerWrapper;
+import mir.util.GeneratorFormatAdapters;
+import mir.util.RewindableIterator;
+import org.apache.commons.beanutils.MethodUtils;
+import org.apache.commons.beanutils.PropertyUtils;
 
 
 public class FreemarkerGenerator implements Generator {
@@ -90,7 +89,7 @@ public class FreemarkerGenerator implements Generator {
     return new IteratorAdapter(anIterator);
   }
 
-  private static TemplateMethodModel makeFunctionAdapter(Generator.GeneratorFunction aFunction) {
+  private static TemplateMethodModel makeFunctionAdapter(Generator.Function aFunction) {
     return new FunctionAdapter(aFunction);
   }
 
@@ -104,10 +103,10 @@ public class FreemarkerGenerator implements Generator {
 
     if (anObject instanceof TemplateModel)
       return (TemplateModel) anObject;
-    else if (anObject instanceof Generator.GeneratorFunction)
-      return makeFunctionAdapter((Generator.GeneratorFunction) anObject);
+    else if (anObject instanceof Generator.Function)
+      return makeFunctionAdapter((Generator.Function) anObject);
     else if (anObject instanceof Integer)
-      return makeStringAdapter(((Integer) anObject).toString());
+      return makeStringAdapter(anObject.toString());
     else if (anObject instanceof Boolean) {
       if (((Boolean) anObject).booleanValue())
         return makeStringAdapter("1");
@@ -181,7 +180,7 @@ public class FreemarkerGenerator implements Generator {
     private IteratorAdapter(Iterator anIterator) {
       iterator = anIterator;
 
-      valuesCache = new Vector();
+      valuesCache = new ArrayList();
       position=0;
 
 
@@ -249,7 +248,7 @@ public class FreemarkerGenerator implements Generator {
 
     private ListAdapter(List aList) {
       list = aList;
-      valuesCache = new Vector();
+      valuesCache = new ArrayList();
       position=0;
     }
 
@@ -299,9 +298,9 @@ public class FreemarkerGenerator implements Generator {
   }
 
   private static class FunctionAdapter implements TemplateMethodModel {
-    private Generator.GeneratorFunction function;
+    private Generator.Function function;
 
-    public FunctionAdapter(Generator.GeneratorFunction aFunction) {
+    public FunctionAdapter(Generator.Function aFunction) {
       function = aFunction;
     }
 
@@ -352,11 +351,11 @@ public class FreemarkerGenerator implements Generator {
     }
   }
 
-  public static class FreemarkerGeneratorLibrary implements GeneratorLibrary {
+  public static class FreemarkerGeneratorLibrary implements Library {
     private FileTemplateCache templateCache;
 
-    public FreemarkerGeneratorLibrary(String aTemplateRoot) {
-      templateCache = new FileTemplateCache( aTemplateRoot+"/" );
+    public FreemarkerGeneratorLibrary(File aTemplateRoot) {
+      templateCache = new FileTemplateCache(aTemplateRoot);
       templateCache.setLoadingPolicy(FileTemplateCache.LOAD_ON_DEMAND);
     }
 
@@ -371,15 +370,16 @@ public class FreemarkerGenerator implements Generator {
     }
   }
 
-  public static class FreemarkerGeneratorLibraryFactory implements GeneratorLibraryFactory {
-    private String basePath;
+  public static class FreemarkerGeneratorLibraryFactory implements LibraryFactory {
+    private File basePath;
 
-    public FreemarkerGeneratorLibraryFactory(String aBasePath) {
+    public FreemarkerGeneratorLibraryFactory(File aBasePath) {
       basePath = aBasePath;
     }
 
-    public GeneratorLibrary makeLibrary(String anInitializationString) {
-      return new FreemarkerGeneratorLibrary(basePath+anInitializationString);
+    public Library makeLibrary(String anInitializationString) {
+      // todo: the initialization string should be parsed
+      return new FreemarkerGeneratorLibrary(new File(basePath, anInitializationString));
     };
   }
 }
index 3d46e47..805d0cc 100755 (executable)
@@ -37,22 +37,27 @@ import java.util.Map;
 
 import mir.log.LoggerWrapper;
 
+/**
+ * Interface representing a "generator", typically a template engine/
+ */
 public interface Generator {
   public void generate(Object anOutputWriter, Map aValues, LoggerWrapper aLogger) throws GeneratorExc, GeneratorFailure;
 
-  public static interface GeneratorLibrary {
+  public static interface Library {
     public Generator makeGenerator(String anIdentifier) throws GeneratorExc, GeneratorFailure;
   }
 
-  public static interface GeneratorLibraryFactory {
-    public GeneratorLibrary makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure ;
+  public static interface LibraryFactory {
+    public Library makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure ;
   }
 
-  public static interface GeneratorFunction {
+  /** interface for a generator implementation independent function */
+  public static interface Function {
+    /** performs the function with the given parameters */
     public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure;
   }
 
-  public static interface GeneratorTransformer {
+  public static interface Transformer {
     public void perform(Reader aSource, PrintWriter anOutput) throws GeneratorExc, GeneratorFailure;
   }
 }
index cfd49e0..298723d 100755 (executable)
@@ -33,14 +33,15 @@ package mir.generator;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
 
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.util.CachingRewindableIterator;
-import mir.util.ResourceBundleGeneratorFunction;
+import mir.bundle.Bundle;
+import mir.util.generator.BundleGeneratorFunction;
 import mircoders.global.MirGlobal;
 
-import org.apache.struts.util.MessageResources;
-
 
 
 public class GeneratorHelper {
@@ -49,47 +50,34 @@ public class GeneratorHelper {
    */
 
   public static Map makeBasicGenerationData(Locale[] aLocales, String aBundle, String aDefaultBundle) throws GeneratorExc{
-    try{
-    Map result = new HashMap();
-    MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(result);
-    
-    
-    Object languages =
-      new CachingRewindableIterator(
-       new EntityIteratorAdapter( "", "id", 30,
-          MirGlobal.localizer().dataModel().adapterModel(), "language"));
+    try {
+      Map result = new HashMap();
+      MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(result);
+
+      Object languages = new CachingRewindableIterator(new EntityIteratorAdapter("", "id", 30, MirGlobal.localizer().dataModel().adapterModel(), "language"));
 
-      Object topics =
-       new CachingRewindableIterator(
-         new EntityIteratorAdapter("", "id", 30,
-           MirGlobal.localizer().dataModel().adapterModel(), "topic"));
+      Object topics = new CachingRewindableIterator(new EntityIteratorAdapter("", "id", 30, MirGlobal.localizer().dataModel().adapterModel(), "topic"));
 
-      Object articleTypes =
-       new CachingRewindableIterator(
-         new EntityIteratorAdapter( "", "id", 30,
-           MirGlobal.localizer().dataModel().adapterModel(), "articleType"));
+      Object articleTypes = new CachingRewindableIterator(new EntityIteratorAdapter("", "id", 30, MirGlobal.localizer().dataModel().adapterModel(), "articleType"));
 
-      Object commentStatuses =
-       new CachingRewindableIterator(
-         new EntityIteratorAdapter( "", "id", 30,
-           MirGlobal.localizer().dataModel().adapterModel(), "commentStatus"));
+      Object commentStatuses = new CachingRewindableIterator(new EntityIteratorAdapter("", "id", 30, MirGlobal.localizer().dataModel().adapterModel(), "commentStatus"));
 
       result.put("commentstatuses", commentStatuses);
       result.put("articletypes", articleTypes);
       result.put("languages", languages);
       result.put("topics", topics);
-      
-      result.put( "lang",
-                 new ResourceBundleGeneratorFunction( aLocales,
-                   new MessageResources[] { MessageResources.getMessageResources(aBundle),
-                     MessageResources.getMessageResources(aDefaultBundle)}));
-
 
+      List bundles = new ArrayList();
+      for (int i=0; i<aLocales.length; i++) {
+        bundles.add(MirGlobal.getBundleFactory().getBundle(aBundle, new String[] { aLocales[i].getLanguage()} ));
+        bundles.add(MirGlobal.getBundleFactory().getBundle(aDefaultBundle, new String[] { aLocales[i].getLanguage()} ));
+      }
+      result.put("lang", new BundleGeneratorFunction((Bundle[]) bundles.toArray(new Bundle[0])));
 
-    return result;
+      return result;
     }
-    catch (Throwable t){
-      throw new GeneratorExc(t.getMessage());
+    catch (Throwable t) {
+      throw new GeneratorFailure(t);
     }
   }
 }
index 3f19fc0..7ee9630 100755 (executable)
@@ -44,15 +44,15 @@ public class GeneratorLibraryRepository {
     logger = new LoggerWrapper("Generator");
   }
 
-  public void registerLibraryFactory(String aName, Generator.GeneratorLibraryFactory aFactory) {
+  public void registerLibraryFactory(String aName, Generator.LibraryFactory aFactory) {
     factories.put(aName, aFactory);
   }
 
-  public Generator.GeneratorLibrary constructLibrary(String aName, String aParameters) throws GeneratorExc {
+  public Generator.Library constructLibrary(String aName, String aParameters) throws GeneratorExc {
     if (!factories.containsKey(aName))
       throw new GeneratorExc("Unknown library factory: "+aName);
 
-    return ((Generator.GeneratorLibraryFactory) factories.get(aName)).makeLibrary(aParameters);
+    return ((Generator.LibraryFactory) factories.get(aName)).makeLibrary(aParameters);
   }
 
   private final static String SPACE = "[\t\n\r ]*";
@@ -63,39 +63,40 @@ public class GeneratorLibraryRepository {
   private final static String FACTORY_PARAMETERS = "[^)]*";
   private final static String SEMICOLON = ";";
 
-  public Generator.GeneratorLibrary constructCompositeLibrary(String aSpecification) throws GeneratorExc, GeneratorFailure {
+  public Generator.Library constructCompositeLibrary(String aSpecification[]) throws GeneratorExc, GeneratorFailure {
     String identifier;
     String factory;
     String factoryParameters;
     CompositeGeneratorLibrary result = new CompositeGeneratorLibrary();
     boolean first=true;
 
-    SimpleParser parser = new SimpleParser(aSpecification);
-    try {
-      parser.skip(SPACE);
-      while (!parser.isAtEnd()) {
-        identifier = parser.parse(IDENTIFIER, "library key expected");
+    for (int i=0; i<aSpecification.length; i++) {
+      SimpleParser parser = new SimpleParser(aSpecification[i]);
+      try {
         parser.skip(SPACE);
-        parser.parse(EQUALS, "'=' expected");
-        parser.skip(SPACE);
-        factory = parser.parse(IDENTIFIER, "factory name expected");
-        parser.skip(SPACE);
-        parser.parse(LEFT_PARENTHESIS, "'(' expected");
-        factoryParameters = parser.parse(FACTORY_PARAMETERS, "parameters expected");
-        parser.parse(RIGHT_PARENTHESIS, "')' expected");
+        while (!parser.isAtEnd()) {
+          identifier = parser.parse(IDENTIFIER, "library key expected");
+          parser.skip(SPACE);
+          parser.parse(EQUALS, "'=' expected");
+          parser.skip(SPACE);
+          factory = parser.parse(IDENTIFIER, "factory name expected");
+          parser.skip(SPACE);
+          parser.parse(LEFT_PARENTHESIS, "'(' expected");
+          factoryParameters = parser.parse(FACTORY_PARAMETERS, "parameters expected");
+          parser.parse(RIGHT_PARENTHESIS, "')' expected");
 
-        result.addLibrary(identifier, constructLibrary(factory, factoryParameters), first);
-        first=false;
-        parser.skip(SPACE);
+          result.addLibrary(identifier, constructLibrary(factory, factoryParameters), first);
+          first=false;
+          parser.skip(SPACE);
 
-        if (!parser.isAtEnd()) {
-          parser.parse(SEMICOLON, "; expected");
+          if (!parser.isAtEnd()) {
+            parser.parse(SEMICOLON, "; expected");
+          }
         }
       }
-    }
-    catch (Exception e) {
-      e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
-      throw new GeneratorFailure("Failed to construct generator library: " + e.getMessage(), e);
+      catch (Exception e) {
+        throw new GeneratorFailure("Failed to construct generator library: " + e.getMessage(), e);
+      }
     }
 
     return result;
index 7be3eed..210267a 100755 (executable)
 package mir.generator;
 
 import java.io.PrintWriter;
+import java.io.File;
 import java.util.Map;
 
 import mir.generator.tal.MirExpressionParser;
-import mir.generator.tal.template.TALTemplate;
+import mir.generator.tal.template.Template;
 import mir.generator.tal.TALTemplateEngine;
 import mir.generator.tal.interfaces.TALLogger;
 import mir.log.LoggerWrapper;
@@ -41,7 +42,6 @@ import mir.log.LoggerWrapper;
 public class TALGenerator implements Generator {
   private String templateIdentifier;
   private TALGeneratorLibrary library;
-  private static LoggerWrapper logger = new LoggerWrapper("Generator.velocity");
 
   public TALGenerator(String aTemplate, TALGeneratorLibrary aLibrary) {
     templateIdentifier = aTemplate;
@@ -49,7 +49,7 @@ public class TALGenerator implements Generator {
   }
 
   public void generate(Object anOutputWriter, Map aValues, final LoggerWrapper aLogger) throws GeneratorExc, GeneratorFailure {
-    TALTemplate template;
+    Template template;
 
     try {
       template = library.engine.loadTemplate(templateIdentifier);
@@ -58,38 +58,41 @@ public class TALGenerator implements Generator {
         throw new GeneratorExc("TALGeneratorLibrary: Can't find template " + templateIdentifier);
       }
 
-      template.processTemplate(aValues, (PrintWriter) anOutputWriter,
+      template.process(aValues, (PrintWriter) anOutputWriter,
           new TALLogger() {
-        public void debug(String anObject, String aMessage) {
-          aLogger.debug(anObject + ": " + aMessage);
+            public void debug(String anObject, String aMessage) {
+              aLogger.debug(anObject + ": " + aMessage);
+            }
+
+            public void info(String anObject, String aMessage) {
+              aLogger.info(anObject + ": " + aMessage);
+            }
+
+            public void warning(String anObject, String aMessage) {
+              aLogger.warn(anObject + ": " + aMessage);
+            }
+
+            public void error(String anObject, String aMessage) {
+              aLogger.error(anObject + ": " + aMessage);
+            }
+
+            public void fatal(String anObject, String aMessage) {
+              aLogger.fatal(anObject + ": " + aMessage);
+            }
+          },
+          library.engine);
         }
-
-        public void info(String anObject, String aMessage) {
-          aLogger.info(anObject + ": " + aMessage);
-        }
-
-        public void warning(String anObject, String aMessage) {
-          aLogger.warn(anObject + ": " + aMessage);
-        }
-
-        public void error(String anObject, String aMessage) {
-          aLogger.error(anObject + ": " + aMessage);
-        }
-
-        public void fatal(String anObject, String aMessage) {
-          aLogger.fatal(anObject + ": " + aMessage);
-        }
-      });
-    }
     catch (Throwable t) {
+      ((PrintWriter) anOutputWriter).println("ERROR: " + t.toString());
+
       throw new GeneratorFailure(t);
     }
   }
 
-  public static class TALGeneratorLibrary implements GeneratorLibrary {
+  public static class TALGeneratorLibrary implements Library {
     private TALTemplateEngine engine;
 
-    public TALGeneratorLibrary(String aTemplateRoot) throws GeneratorExc, GeneratorFailure {
+    public TALGeneratorLibrary(File aTemplateRoot) throws GeneratorExc, GeneratorFailure {
       engine = new TALTemplateEngine(new MirExpressionParser(), aTemplateRoot);
     }
 
@@ -98,15 +101,15 @@ public class TALGenerator implements Generator {
     }
   }
 
-  public static class TALGeneratorLibraryFactory implements GeneratorLibraryFactory {
-    private String basePath;
+  public static class TALGeneratorLibraryFactory implements LibraryFactory {
+    private File basePath;
 
-    public TALGeneratorLibraryFactory(String aBasePath) {
+    public TALGeneratorLibraryFactory(File aBasePath) {
       basePath = aBasePath;
     }
 
-    public GeneratorLibrary makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure {
-      return new TALGeneratorLibrary(basePath+anInitializationString);
+    public Library makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure {
+      return new TALGeneratorLibrary(new File(basePath, anInitializationString));
     };
   }
 }
index a6c0a77..1735701 100755 (executable)
@@ -31,6 +31,7 @@ package mir.generator;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.io.File;
 import java.util.AbstractList;
 import java.util.Date;
 import java.util.HashMap;
@@ -42,7 +43,6 @@ import java.util.Vector;
 import org.apache.commons.beanutils.MethodUtils;
 import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.context.Context;
 import org.apache.velocity.exception.ParseErrorException;
@@ -105,37 +105,6 @@ public class VelocityGenerator implements Generator {
 
   /**
    *
-   * <p>Title: </p>
-   * <p>Description: </p>
-   * <p>Copyright: Copyright (c) 2003</p>
-   * <p>Company: </p>
-   * @author not attributable
-   * @version 1.0
-   */
-  private static class ContextAdapter implements Context {
-    public boolean containsKey(java.lang.Object key) {
-      return false;
-    }
-
-    public Object get(java.lang.String key) {
-      return null;
-    }
-
-    public Object[] getKeys() {
-      return new Object[] {};
-    }
-
-    public Object put(java.lang.String key, java.lang.Object value) {
-      return null;
-    }
-
-    public Object remove(java.lang.Object key) {
-      return null;
-    }
-  }
-
-  /**
-   *
    * @param aMap
    * @return
    */
@@ -166,7 +135,7 @@ public class VelocityGenerator implements Generator {
    * @param aFunction
    * @return
    */
-  private static Object makeFunctionAdapter(Generator.GeneratorFunction aFunction) {
+  private static Object makeFunctionAdapter(Generator.Function aFunction) {
     return new FunctionAdapter(aFunction);
   }
 
@@ -217,8 +186,8 @@ public class VelocityGenerator implements Generator {
     if (anObject instanceof Context)
       return anObject;
 
-    else if (anObject instanceof Generator.GeneratorFunction)
-      return makeFunctionAdapter((Generator.GeneratorFunction) anObject);
+    else if (anObject instanceof Generator.Function)
+      return makeFunctionAdapter((Generator.Function) anObject);
     else if (anObject instanceof Integer)
       return anObject;
     else if (anObject instanceof Boolean)
@@ -249,13 +218,13 @@ public class VelocityGenerator implements Generator {
    * @version 1.0
    */
   public static class FunctionAdapter implements VelocityAdapter {
-    private GeneratorFunction function;
+    private Function function;
 
     public Object getOriginal() {
       return function;
     }
 
-    private FunctionAdapter(GeneratorFunction aFunction) {
+    private FunctionAdapter(Function aFunction) {
       function = aFunction;
     }
 
@@ -364,14 +333,11 @@ public class VelocityGenerator implements Generator {
   private static class IteratorAdapter extends AbstractList implements VelocityAdapter  {
     private Iterator iterator;
     private List valuesCache;
-    private int position;
 
     private IteratorAdapter(Iterator anIterator) {
       iterator = anIterator;
 
       valuesCache = new Vector();
-      position=0;
-
 
       if (iterator instanceof RewindableIterator) {
         ((RewindableIterator) iterator).rewind();
@@ -423,13 +389,11 @@ public class VelocityGenerator implements Generator {
   private static class ListAdapter extends AbstractList implements VelocityAdapter  {
     private List list;
     private List valuesCache;
-    private int position;
 
     private ListAdapter(List aList) {
       list = aList;
 
       valuesCache = new Vector();
-      position=0;
     }
 
     private void getUntil(int anIndex) {
@@ -569,46 +533,22 @@ public class VelocityGenerator implements Generator {
    * @author not attributable
    * @version 1.0
    */
-  public static class VelocityGeneratorLibrary implements GeneratorLibrary {
+  public static class VelocityGeneratorLibrary implements Library {
     private VelocityEngine engine;
 
-    public VelocityGeneratorLibrary(String aTemplateRoot) throws GeneratorExc, GeneratorFailure {
+    public VelocityGeneratorLibrary(File aTemplateRoot) throws GeneratorExc, GeneratorFailure {
       try {
         engine = new VelocityEngine();
         try {
           engine.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
-        }
-        catch (Throwable t) {
-          logger.error(VelocityEngine.RESOURCE_LOADER);
-        }
-
-        try {
           engine.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
-        }
-        catch (Throwable t) {
-          logger.error("file.resource.loader.class");
-        }
-
-        try {
-          engine.setProperty("file.resource.loader.path", aTemplateRoot);
-        }
-        catch (Throwable t) {
-          logger.error("file.resource.loader.path");
-
-        }
-        try {
+          engine.setProperty("file.resource.loader.path", aTemplateRoot.getAbsolutePath());
           engine.setProperty("file.resource.loader.cache", "true");
         }
         catch (Throwable t) {
-          logger.error("file.resource.loader.cache");
-
-        }
-        try {
-          engine.setProperty("file.resource.loader.modificationCheckInterval", "10");
-        }
-        catch (Throwable t) {
-          logger.error("file.resource.loader.modificationCheckInterval");
+          logger.error("Error while constructing library: " + t.toString());
 
+          throw new GeneratorFailure(t);
         }
 
         try {
@@ -642,15 +582,15 @@ public class VelocityGenerator implements Generator {
    * @author not attributable
    * @version 1.0
    */
-  public static class VelocityGeneratorLibraryFactory implements GeneratorLibraryFactory {
-    private String basePath;
+  public static class VelocityGeneratorLibraryFactory implements LibraryFactory {
+    private File basePath;
 
-    public VelocityGeneratorLibraryFactory(String aBasePath) {
+    public VelocityGeneratorLibraryFactory(File aBasePath) {
       basePath = aBasePath;
     }
 
-    public GeneratorLibrary makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure {
-      return new VelocityGeneratorLibrary(basePath+anInitializationString);
+    public Library makeLibrary(String anInitializationString) throws GeneratorExc, GeneratorFailure {
+      return new VelocityGeneratorLibrary(new File(basePath, anInitializationString));
     };
   }
 }
index df0c2b6..c9f042b 100755 (executable)
@@ -35,10 +35,10 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
 
 public class CachingFileLoader {
   private Map cachedObjects;
@@ -49,7 +49,7 @@ public class CachingFileLoader {
   public CachingFileLoader(int aCapacity, CachedFileObjectFactory aFactory) {
     capacity = aCapacity;
     cachedObjects = new HashMap();
-    history = new Vector();
+    history = new ArrayList();
     factory = aFactory;
   }
 
index 3d10c60..3413fc5 100755 (executable)
@@ -143,4 +143,12 @@ public class MirExpressionParser implements TALExpressionParser {
     }
   }
 
+  public Object evaluatePseudoVariable(Object aContext, String aName) {
+    try {
+      return ParameterExpander.getObjectField(aContext, aName);
+    }
+    catch (Throwable t) {
+      throw new TALFailure(t);
+    }
+  }
 }
\ No newline at end of file
diff --git a/source/mir/generator/tal/SimpleTemplateNodeLibraryRegistry.java b/source/mir/generator/tal/SimpleTemplateNodeLibraryRegistry.java
new file mode 100755 (executable)
index 0000000..561f50a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.generator.tal;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import mir.generator.tal.template.TemplateNodeLibraryRegistry;
+import mir.generator.tal.template.TemplateNodeLibrary;
+
+public class SimpleTemplateNodeLibraryRegistry implements TemplateNodeLibraryRegistry {
+  private Map urlToLibrary;
+  private Map prefixToLibrary;
+
+  public SimpleTemplateNodeLibraryRegistry() {
+    urlToLibrary = new HashMap();
+    prefixToLibrary = new HashMap();
+  }
+
+  public void registerTemplateNodeLibrary(String aPrefix, String aUrl, TemplateNodeLibrary aLibrary) {
+    urlToLibrary.put(aUrl, aLibrary);
+    prefixToLibrary.put(aPrefix, aLibrary);
+  }
+
+  public TemplateNodeLibrary findLibraryForUrl(String aUrl) {
+    return (TemplateNodeLibrary) urlToLibrary.get(aUrl);
+  }
+
+  public TemplateNodeLibrary findLibraryForPrefix(String aPrefix) {
+    return (TemplateNodeLibrary) prefixToLibrary.get(aPrefix);
+  }
+}
index 071d333..aa3fb76 100755 (executable)
@@ -34,59 +34,79 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map;
-import java.util.HashMap;
+import java.util.List;
 
 import mir.generator.tal.interfaces.TALExpressionParser;
-import mir.generator.tal.template.TALTemplate;
-import mir.generator.tal.template.TALTemplateNodeLibrary;
-import mir.generator.tal.template.TALBasicTemplateNodeLibrary;
+import mir.generator.tal.template.*;
+import mir.util.StringRoutines;
 
-public class TALTemplateEngine {
+public class TALTemplateEngine implements TemplateLibrary {
   private TALExpressionParser expressionParser;
-  private String basePath;
+  private File basePath;
   private CachingFileLoader loader;
 
-  private Map urlToLibrary;
-  private Map prefixToLibrary;
+  private SimpleTemplateNodeLibraryRegistry registry;
 
-  public TALTemplateEngine(TALExpressionParser anExpressionParser, String aBasePath) {
+  public TALTemplateEngine(TALExpressionParser anExpressionParser, File aBasePath) {
     expressionParser = anExpressionParser;
     basePath = aBasePath;
     loader = new CachingFileLoader(100, new TemplateFactory());
 
-    urlToLibrary = new HashMap();
-    prefixToLibrary = new HashMap();
+    registry = new SimpleTemplateNodeLibraryRegistry();
 
-    registerTemplateNodeLibrary("tal", "http://xml.zope.org/namespaces/tal", new TALBasicTemplateNodeLibrary("tal", "http://xml.zope.org/namespaces/tal"));
+    registerTemplateNodeLibrary("tal", "http://xml.zope.org/namespaces/tal",
+        new CoreTemplateNodeLibrary("tal", "http://xml.zope.org/namespaces/tal"));
     registerTemplateNodeLibrary("metal", "http://xml.zope.org/namespaces/metal",
-        new TALBasicTemplateNodeLibrary("metal", "http://xml.zope.org/namespaces/metal"));
-
+        new MacroTemplateNodeLibrary("metal", "http://xml.zope.org/namespaces/metal"));
   }
 
-  public void registerTemplateNodeLibrary(String aPrefix, String aUrl, TALTemplateNodeLibrary aLibrary) {
-    urlToLibrary.put(aUrl, aLibrary);
-    prefixToLibrary.put(aPrefix, aLibrary);
+  public void registerTemplateNodeLibrary(String aPrefix, String aUrl, TemplateNodeLibrary aLibrary) {
+    registry.registerTemplateNodeLibrary(aPrefix, aUrl, aLibrary);
   }
 
-  public TALTemplate loadTemplate(String aName) throws IOException {
-    File location = new File(basePath, aName);
-    return (TALTemplate) loader.retrieveFile(location.getCanonicalPath());
-  }
+  public Template loadTemplate(String aName) throws IOException, TemplateProcessingException {
+    List parts = StringRoutines.splitString(aName, "#");
+
+    if (parts.size()!=1 && parts.size()!=2) {
+      throw new TemplateProcessingException("Invalid template name: " + aName);
+    }
+
+    File location = new File(basePath, (String) parts.get(0));
+
+    Template baseTemplate = (Template) loader.retrieveFile(location.getCanonicalPath());
+
+    if (baseTemplate!=null && parts.size()>1) {
+      Map definitions = (Map) baseTemplate.getContext().get(MacroTemplateNodeLibrary.MACRO_DEFINITIONS_KEY);
+      if (definitions==null || !definitions.containsKey(parts.get(1))) {
+        throw new TemplateProcessingException("No macro '"+(String) parts.get(1)+"' found in template '" + (String) parts.get(0) + "'");
+      }
 
-  public TALTemplateNodeLibrary getLibraryForPrefix(String aPrefix) {
-    return (TALTemplateNodeLibrary) prefixToLibrary.get(aPrefix);
+      return new Template(expressionParser, (TemplateNode) definitions.get(parts.get(1)), baseTemplate.getContext());
+    }
+    else {
+      return baseTemplate;
+    }
+
+
+
+//      public Template(TALExpressionParser aParser, TemplateNode aRootNode, Map aTemplateContext) {
   }
 
-  public TALTemplateNodeLibrary getLibraryForUrl(String aUrl) {
-    return (TALTemplateNodeLibrary) urlToLibrary.get(aUrl);
+  public Template lookupTemplate(String aName) throws TemplateProcessingException {
+    try {
+      return loadTemplate(aName);
+    }
+    catch (IOException e) {
+      throw new TemplateProcessingException("Can't load template " + aName + ": " + e.toString(), e);
+    }
   }
 
   private class TemplateFactory implements CachingFileLoader.CachedFileObjectFactory {
     public Object constructObject(InputStream aStream) {
       try {
-        TALTemplateParser parser = new TALTemplateParser(TALTemplateEngine.this);
+        TALTemplateParser parser = new TALTemplateParser(registry);
 
-        return parser .parse(aStream, expressionParser);
+        return parser.parse(aStream, expressionParser);
       }
       catch (Throwable t) {
         throw new TALFailure(t);
index d37f95f..ff1596f 100755 (executable)
@@ -39,13 +39,15 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.HashMap;
 
 import mir.generator.tal.interfaces.TALExpressionParser;
 import mir.generator.tal.template.CompositeTemplateNode;
 import mir.generator.tal.template.PlainTextTemplateNode;
-import mir.generator.tal.template.TALTemplate;
-import mir.generator.tal.template.TALTemplateNodeLibrary;
+import mir.generator.tal.template.Template;
+import mir.generator.tal.template.TemplateNodeLibrary;
 import mir.generator.tal.template.TemplateNode;
+import mir.generator.tal.template.TemplateNodeLibraryRegistry;
 import mir.util.HTMLRoutines;
 import mir.util.xml.SectionHandler;
 import mir.util.xml.XMLName;
@@ -54,21 +56,18 @@ import mir.util.xml.XMLParserExc;
 import mir.util.xml.XMLParserFailure;
 import mir.util.xml.XMLReaderTool;
 
-// TODO: add a templatelibrary repository and remove dependency of TALTemplateEngine
-
 public class TALTemplateParser {
-  private TALTemplateEngine engine;
+  private TemplateNodeLibraryRegistry registry;
 
-  //private static final String TAL_PREFIX = "tal";
-  public TALTemplateParser(TALTemplateEngine anEngine) {
-    engine = anEngine;
+  public TALTemplateParser(TemplateNodeLibraryRegistry aRegistry) {
+    registry = aRegistry;
   }
 
-  public TALTemplate parse(String aData, TALExpressionParser aParser) throws TALExc, TALFailure {
+  public Template parse(String aData, TALExpressionParser aParser) throws TALExc, TALFailure {
     return parse(new StringReader(aData), aParser);
   }
 
-  public TALTemplate parse(File aFile, TALExpressionParser aParser) throws TALExc, TALFailure {
+  public Template parse(File aFile, TALExpressionParser aParser) throws TALExc, TALFailure {
     try {
       return parse(new BufferedInputStream(new FileInputStream(aFile), 1024*128), aParser);
     }
@@ -76,12 +75,13 @@ public class TALTemplateParser {
       throw new TALFailure(e);
     }
   }
-  public TALTemplate parse(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure {
+  public Template parse(InputStream anInputStream, TALExpressionParser aParser) throws TALExc, TALFailure {
     return parse(new InputStreamReader(anInputStream), aParser);
   }
 
-  public TALTemplate parse(Reader aReader, TALExpressionParser aParser) throws TALExc, TALFailure {
-    TALHandler handler = new TALHandler(aParser);
+  public Template parse(Reader aReader, TALExpressionParser aParser) throws TALExc, TALFailure {
+    Map templateContext = new HashMap();
+    TALHandler handler = new TALHandler(aParser, templateContext);
 
     try {
       XMLParserEngine.getInstance().parse("html", aReader, handler);
@@ -90,28 +90,33 @@ public class TALTemplateParser {
       throw new TALFailure(e);
     }
 
-    return new TALTemplate(aParser, handler.getNode());
+    return new Template(aParser, handler.getNode(), templateContext);
   }
 
   protected class TALHandler implements SectionHandler {
     private CompositeTemplateNode compositeNode;
     private StringBuffer data;
+    private StringBuffer plainData;
     private TALExpressionParser parser;
     private String currentTag;
-    private TALTemplateNodeLibrary library;
+    private TemplateNodeLibrary library;
     private XMLName tag;
     private Map attributes;
+    private Map templateContext;
 
-    public TALHandler(TALExpressionParser aParser) {
+    public TALHandler(TALExpressionParser aParser, Map aTemplateContext) {
       parser = aParser;
       data = new StringBuffer();
+      plainData = new StringBuffer();
       compositeNode = new CompositeTemplateNode();
+      templateContext = aTemplateContext;
     }
 
     private void flushData() {
       if (data.length()!=0) {
-        compositeNode.appendSubNode(new PlainTextTemplateNode(data.toString()));
+        compositeNode.appendSubNode(new PlainTextTemplateNode(data.toString(), plainData.toString()));
         data.delete(0, data.length());
+        plainData.delete(0, plainData.length());
       }
     }
 
@@ -119,15 +124,15 @@ public class TALTemplateParser {
       appendCode(anExtraData);
     }
 
-    public TALTemplateNodeLibrary findLibrary(XMLName aName) {
-      TALTemplateNodeLibrary result = null;
+    public TemplateNodeLibrary findLibrary(XMLName aName) {
+      TemplateNodeLibrary result = null;
 
       if (aName.getNamespaceURI()!=null) {
-        result = engine.getLibraryForUrl(aName.getNamespaceURI());
+        result = registry.findLibraryForUrl(aName.getNamespaceURI());
       }
 
       if ((result == null) && (aName.getPrefix()!=null) && (aName.getPrefix().length()>0)) {
-        result = engine.getLibraryForPrefix(aName.getPrefix());
+        result = registry.findLibraryForPrefix(aName.getPrefix());
       }
 
       return result;
@@ -155,23 +160,31 @@ public class TALTemplateParser {
           appendText((String) entry.getValue());
           appendCode("\"");
         }
-        appendCode(">");
       }
       else {
         tag = aTag;
         attributes = anAttributes;
       }
 
-      return new TALHandler(parser);
+      return new TALHandler(parser, templateContext);
     };
 
     public void endElement(mir.util.xml.SectionHandler aHandler) throws XMLParserExc {
       if (library == null) {
-        appendSubNode(((TALHandler) aHandler).getNode());
-        appendCode("</"+currentTag+">");
+        TemplateNode subNode = ((TALHandler) aHandler).getNode();
+        if (subNode instanceof CompositeTemplateNode &&
+            ((CompositeTemplateNode) subNode).isEmpty()) {
+          appendCode(" />");
+        }
+        else {
+          appendCode(">");
+          appendSubNode(subNode);
+          appendCode("</"+currentTag+">");
+        }
       }
       else {
-        appendSubNode(library.constructTemplateNode(parser, tag, attributes, ((TALHandler) aHandler).getNode()));
+        appendSubNode(
+            library.constructTemplateNode(parser, tag, attributes, ((TALHandler) aHandler).getNode(), templateContext));
         tag = null;
         attributes = null;
       }
@@ -189,6 +202,7 @@ public class TALTemplateParser {
 
     protected void appendText(String aText) {
       data.append(HTMLRoutines.encodeHTML(aText));
+      plainData.append(aText);
     }
 
     public void finishSection() throws XMLParserExc {
index 88be864..1eb475d 100755 (executable)
 package mir.generator.tal;
 
 import java.io.PrintWriter;
+import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 
 import mir.generator.tal.interfaces.TALLogger;
-import mir.generator.tal.template.TALTemplate;
-import mir.util.HTMLRoutines;
+import mir.generator.tal.template.Template;
+import mir.generator.tal.template.TemplateLibrary;
+import mir.generator.tal.template.TemplateProcessingException;
+import mir.generator.tal.template.CoreTemplateNodeLibrary;
+import mir.generator.tal.template.MacroTemplateNodeLibrary;
 
 public class TALTest {
   public static void main(String args[]) {
     try {
-      System.out.println(HTMLRoutines.resolveHTMLEntites("&eacute;&eacute;ad&a;&aaddsd&#;&eacute;&&sdf&f;&eacute;aap"));
+      final SimpleTemplateNodeLibraryRegistry registry = new SimpleTemplateNodeLibraryRegistry();
 
-      TALTemplateEngine engine = new TALTemplateEngine(new MirExpressionParser(), "m:/biotechdev/mir/etc/producertal/");
+      registry.registerTemplateNodeLibrary("tal", "http://xml.zope.org/namespaces/tal",
+          new CoreTemplateNodeLibrary("tal", "http://xml.zope.org/namespaces/tal"));
+      registry.registerTemplateNodeLibrary("metal", "http://xml.zope.org/namespaces/metal",
+          new MacroTemplateNodeLibrary("metal", "http://xml.zope.org/namespaces/metal"));
+
+      TemplateLibrary library = new TemplateLibrary() {
+        public Template lookupTemplate(String aTemplateName) throws TemplateProcessingException {
+          try {
+            TALTemplateParser parser = new TALTemplateParser(registry);
+
+            if (aTemplateName.equals("a")) {
+              return parser.parse("<test tal:on-error='${exception.message}'><bkla><font tal:content='${sdf'></bkla><td><b><font>bla</font></b></td></font>" +
+                  "<test2 metal:use-macro=\"b#testmacro\"></test2><test3 a='b' tal:attributes='c a:${tagattributes.a}'> </test3> " +
+                  "<test4 tal:content='the content was ${tagcontent}'>bla <b>die</b> bla ></test4><a width='100%'/>" +
+                  "<test5 tal:bla=a><tal:bla/></test5>   </test>", new MirExpressionParser());
+            }
+            else {
+              return parser.parse("<test3><test4 metal:define-macro=\"testmacro\">hoi</test4><test3>", new MirExpressionParser());
+            }
+          }
+          catch (Throwable t) {
+            t.printStackTrace();
+            System.out.println(t.toString());
+            return null;
+          }
+        }
+      };
+
+      Map test = new HashMap();
+
+      Template template = library.lookupTemplate("a");
+
+      PrintWriter p = new PrintWriter(System.out);
+
+      template.process(new HashMap(), p, new TALLogger.TALSystemOutLogger(), library);
+
+      p.close();
+
+    }
+    catch (Throwable t) {
+      System.out.println("Exception: " + t.toString());
+      t.printStackTrace(System.out);
+    }
+  }
+  public static void main2(String args[]) {
+    try {
+      TALTemplateEngine engine = new TALTemplateEngine(
+          new MirExpressionParser(), new File("m:/romania/mir/etc/producer/"));
 
       Map test = new HashMap();
       test.put("name", "zapata");
 
-      TALTemplate template = engine.loadTemplate("frame.template");
+      Template template = engine.loadTemplate("indy-ro-txt.html");
 
       PrintWriter p = new PrintWriter(System.out);
 
-      template.processTemplate(new Object(), p, new TALLogger.TALSystemOutLogger());
+      template.process(new Object(), p, new TALLogger.TALSystemOutLogger(), engine);
 
       p.close();
 
index c8f6d45..bc3106e 100755 (executable)
@@ -50,20 +50,20 @@ public interface TALExpressionParser {
   /**
    * process a direct assignment of an object to a preparsed reference expression
    *
-   * @param aContext
-   * @param aPreparsedReferenceExpression
-   * @param aValue
    */
   public void processDirectAssignment(Object aContext, Object aPreparsedReferenceExpression, Object aValue);
 
-
   /**
    * process an assigment to a pseudo variable. The pseudo variable will have a java
    *   identifier-like name.
    *
-   * @param aContext
-   * @param aPreparsedReferenceExpression
-   * @param aValue
    */
   public void processPseudoAssignment(Object aContext, String aName, Object aValue);
+
+  /**
+   * Retrieve the value of a pseudo variable
+   *
+   */
+  public Object evaluatePseudoVariable(Object aContext, String aName);
+
 }
\ No newline at end of file
index fc2b714..55a6cb0 100755 (executable)
  */\r
 package mir.generator.tal.template;\r
 \r
-import java.util.List;\r
-import java.util.Vector;\r
+import java.util.ArrayList;\r
 import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
 \r
 import mir.generator.tal.interfaces.TALExpressionParser;\r
 import mir.generator.tal.interfaces.TALLogger;\r
-import mir.generator.tal.template.PlainTextTemplateNode;\r
 \r
-public class CompositeTemplateNode\r
-    implements TemplateNode {\r
+/**\r
+ * Template node that is composed of a list of template nodes.\r
+ *\r
+ */\r
+public class CompositeTemplateNode implements TemplateNode {\r
   private List parts;\r
 \r
   public CompositeTemplateNode() {\r
-    parts = new Vector();\r
+    parts = new ArrayList();\r
   }\r
 \r
-  public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination, TALLogger aLogger) throws TemplateProcessingException {\r
+  /** {@inheritDoc} */\r
+  public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination,\r
+      TALLogger aLogger, Map aTemplateContext, TemplateLibrary aLibrary) throws TemplateProcessingException {\r
     Iterator i = parts.iterator();\r
 \r
     while (i.hasNext()) {\r
-      ((TemplateNode) i.next()).process(aParser, aContext, aDestination, aLogger);\r
+      ((TemplateNode) i.next()).process(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);\r
+    }\r
+  }\r
+\r
+  public String getPlainText() {\r
+    StringBuffer result = new StringBuffer();\r
+\r
+    Iterator i = parts.iterator();\r
+    while (i.hasNext()) {\r
+      result.append(((TemplateNode) i.next()).getPlainText());\r
     }\r
+\r
+    return result.toString();\r
   }\r
 \r
+  public boolean isEmpty() {\r
+    return parts.isEmpty();\r
+  }\r
+\r
+  /**\r
+   * Adds a <code>TemplateNode</code> at the end of the chain.\r
+   */\r
   public void appendSubNode(TemplateNode aNode) {\r
     if (aNode instanceof CompositeTemplateNode) {\r
       Iterator i = ((CompositeTemplateNode) aNode).parts.iterator();\r
@@ -60,13 +83,16 @@ public class CompositeTemplateNode
         appendSubNode((TemplateNode) i.next());\r
       }\r
     }\r
-    else if (aNode instanceof PlainTextTemplateNode && parts.size()>0 &&\r
+    else if (aNode instanceof PlainTextTemplateNode &&\r
+             parts.size()>0 &&\r
              (parts.get(parts.size()-1) instanceof PlainTextTemplateNode)) {\r
 \r
       ((PlainTextTemplateNode) parts.get(parts.size()-1)).appendText(((PlainTextTemplateNode) aNode).getText());\r
+      ((PlainTextTemplateNode) parts.get(parts.size()-1)).appendPlainText(((PlainTextTemplateNode) aNode).getPlainText());\r
     }\r
     else {\r
       parts.add(aNode);\r
     }\r
   }\r
+\r
 }\r
diff --git a/source/mir/generator/tal/template/CoreTemplateNodeLibrary.java b/source/mir/generator/tal/template/CoreTemplateNodeLibrary.java
new file mode 100755 (executable)
index 0000000..e806deb
--- /dev/null
@@ -0,0 +1,380 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+\r
+package mir.generator.tal.template;\r
+\r
+import java.util.*;\r
+\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+import mir.generator.tal.interfaces.TALLogger;\r
+import mir.util.HTMLRoutines;\r
+import mir.util.StringRoutines;\r
+import mir.util.xml.XMLName;\r
+import mir.util.xml.XMLParserExc;\r
+import mir.util.xml.XMLReaderTool;\r
+\r
+public class CoreTemplateNodeLibrary implements TemplateNodeLibrary {\r
+  private String prefix;\r
+  private String uri;\r
+\r
+  private boolean isOurTag(XMLName aName) {\r
+    return prefix.equals(aName.getPrefix()) || uri.equals(aName.getNamespaceURI());\r
+  }\r
+\r
+  public CoreTemplateNodeLibrary(String aPrefix, String aUri) {\r
+    prefix = aPrefix;\r
+    uri = aUri;\r
+  }\r
+\r
+  private static final String CONDITION_ATTRIBUTE = "condition";\r
+  private static final String REPEAT_ATTRIBUTE = "repeat";\r
+  private static final String CONTENT_ATTRIBUTE = "content";\r
+  private static final String ERROR_ATTRIBUTE = "on-error";\r
+  private static final String REPLACE_ATTRIBUTE = "replace";\r
+  private static final String DEFINITION_ATTRIBUTE = "define";\r
+  private static final String OMITTAG_ATTRIBUTE = "omit-tag";\r
+  private static final String ATTRIBUTE_ATTRIBUTE = "attributes";\r
+\r
+  public TemplateNode constructTemplateNode(TALExpressionParser aParser, XMLName aTag, Map anAttributes,\r
+      TemplateNode aChildTemplateNode, Map aTemplateContext) throws XMLParserExc {\r
+    TALBasicTemplateNode result = new TALBasicTemplateNode(XMLReaderTool.normalizeXMLName(aTag));\r
+    result.setBody(aChildTemplateNode);\r
+\r
+    if (isOurTag(aTag))\r
+      result.setOmitTag(aParser.preparseTRUE());\r
+\r
+    Iterator i = anAttributes.entrySet().iterator();\r
+    while (i.hasNext()) {\r
+      Map.Entry entry = (Map.Entry) i.next();\r
+      XMLName name = (XMLName) entry.getKey();\r
+\r
+      if (!isOurTag(name)) {\r
+        result.addFixedAttribute(XMLReaderTool.normalizeXMLName(name), (String) entry.getValue());\r
+      }\r
+      else {\r
+        if (name.getLocalName().equalsIgnoreCase(DEFINITION_ATTRIBUTE)) {\r
+          List definitions = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\');\r
+\r
+          Iterator j = definitions.iterator();\r
+          while (j.hasNext())\r
+          {\r
+            List parts = StringRoutines.separateString((String) j.next(), " ");\r
+\r
+            if (parts.size()==2) {\r
+              result.addDefinition(aParser.preparseReferenceExpression((String) parts.get(0)), aParser.preparseExpression((String) parts.get(1)));\r
+            }\r
+          }\r
+        }\r
+        else if (name.getLocalName().equalsIgnoreCase(CONDITION_ATTRIBUTE)) {\r
+          result.setCondition(aParser.preparseBooleanExpression((String) entry.getValue()));\r
+        }\r
+        else if (name.getLocalName().equalsIgnoreCase(CONTENT_ATTRIBUTE)) {\r
+          result.setContent(aParser.preparseStringExpression((String) entry.getValue()));\r
+        }\r
+        else if (name.getLocalName().equalsIgnoreCase(ERROR_ATTRIBUTE)) {\r
+          result.setError(aParser.preparseStringExpression((String) entry.getValue()));\r
+        }\r
+        else if (name.getLocalName().equalsIgnoreCase(OMITTAG_ATTRIBUTE)) {\r
+          if (((String) entry.getValue()).trim().length()==0)\r
+            result.setOmitTag(aParser.preparseTRUE());\r
+          else\r
+            result.setOmitTag(aParser.preparseBooleanExpression((String) entry.getValue()));\r
+        }\r
+        else if (name.getLocalName().equalsIgnoreCase(REPLACE_ATTRIBUTE)) {\r
+          result.setOmitTag(aParser.preparseTRUE());\r
+          result.setContent(aParser.preparseStringExpression((String) entry.getValue()));\r
+        }\r
+        else if (name.getLocalName().equalsIgnoreCase(REPEAT_ATTRIBUTE)) {\r
+          List parts = StringRoutines.separateString((String) entry.getValue(), " ");\r
+\r
+          if (parts.size()==2) {\r
+            result.setRepeat(aParser.preparseReferenceExpression((String) parts.get(0)), aParser.preparseExpression((String) parts.get(1)));\r
+          }\r
+        }\r
+        else if (name.getLocalName().equalsIgnoreCase(ATTRIBUTE_ATTRIBUTE)) {\r
+          List attributes = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\');\r
+\r
+          Iterator j = attributes.iterator();\r
+          while (j.hasNext()) {\r
+            String value = (String) j.next();\r
+            List parts = StringRoutines.separateString(value.trim(), " ");\r
+\r
+            if (parts.size()==2) {\r
+              result.addModifiedAttribute((String) parts.get(0), aParser.preparseExpression((String) parts.get(1)));\r
+            }\r
+            else {\r
+              throw new XMLParserExc(ATTRIBUTE_ATTRIBUTE + " tag should have exactly 2 parts ("+value+")");\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    return result;\r
+  }\r
+\r
+  public static class TALBasicTemplateNode implements TemplateNode {\r
+    private String tag;\r
+    private Map fixedAttributes;\r
+    private Map attributeModifiers;\r
+\r
+    private List definitions;\r
+    private Object condition;\r
+\r
+    private Object repeatVariable;\r
+    private Object repeatExpression;\r
+    private Object contentExpression;\r
+    private Object omitTagExpression;\r
+    private Object errorExpression;\r
+\r
+    private TemplateNode body;\r
+\r
+    public TALBasicTemplateNode(String aTag) {\r
+      tag = aTag;\r
+\r
+      fixedAttributes = new HashMap();\r
+      attributeModifiers = new HashMap();\r
+\r
+      definitions = new ArrayList();\r
+      condition = null;\r
+\r
+      repeatVariable = null;\r
+      repeatExpression = null;\r
+      contentExpression = null;\r
+      omitTagExpression = null;\r
+\r
+      body = null;\r
+    }\r
+\r
+    public void setBody(TemplateNode aBody) {\r
+      body = aBody;\r
+    }\r
+\r
+    public void addFixedAttribute(String aKey, String aValue) {\r
+      fixedAttributes.put(aKey, aValue);\r
+    }\r
+\r
+    public void addModifiedAttribute(String aKey, Object aValue) {\r
+      attributeModifiers.put(aKey, aValue);\r
+    }\r
+\r
+    public void addDefinition(Object aKey, Object aValue) {\r
+      definitions.add(new Definition(aKey, aValue));\r
+    }\r
+\r
+    public void setCondition(Object aCondition) {\r
+      condition = aCondition;\r
+    }\r
+\r
+    public void setRepeat(Object aRepeatVariable, Object aRepeatExpression) {\r
+      repeatVariable = aRepeatVariable;\r
+      repeatExpression = aRepeatExpression;\r
+    }\r
+\r
+    public void setContent(Object aContentExpression) {\r
+      contentExpression = aContentExpression;\r
+    }\r
+\r
+    public void setOmitTag(Object anOmitTagExpression) {\r
+      omitTagExpression = anOmitTagExpression;\r
+    }\r
+\r
+    public void setError(Object anErrorExpression) {\r
+      errorExpression = anErrorExpression;\r
+    }\r
+\r
+    public static class Definition {\r
+      private Object variable;\r
+      private Object expression;\r
+\r
+      public Definition(Object aVariable, Object anExpression) {\r
+        variable = aVariable;\r
+        expression = anExpression;\r
+      }\r
+\r
+      public Object getVariable() {\r
+        return variable;\r
+      }\r
+\r
+      public Object getExpression() {\r
+        return expression;\r
+      }\r
+    }\r
+\r
+    public void process(TALExpressionParser aParser, Object aContext,\r
+        StringBuffer aDestination, TALLogger aLogger, Map aTemplateContext,\r
+        TemplateLibrary aLibrary) throws TemplateProcessingException {\r
+      if (errorExpression != null) {\r
+        StringBuffer destination = new StringBuffer();\r
+\r
+        try {\r
+          outerProcess(aParser, aContext, destination, aLogger, aTemplateContext, aLibrary);\r
+        }\r
+        catch (Throwable t) {\r
+          try {\r
+//            destination.delete(0, destination.length());\r
+            aParser.processPseudoAssignment(aContext, "exception", t);\r
+            destination.insert(0, aParser.evaluateStringExpression(aContext, errorExpression));\r
+            destination.append(" >>>ERROR POSITION<<< ");\r
+          }\r
+          catch (Throwable s) {\r
+            throw new TemplateProcessingException(s);\r
+          }\r
+        }\r
+        finally {\r
+          aDestination.append(destination);\r
+        }\r
+      }\r
+      else {\r
+        outerProcess(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);\r
+      }\r
+    }\r
+\r
+    public String getPlainText() {\r
+      return body.getPlainText();\r
+    }\r
+\r
+    public void outerProcess(TALExpressionParser aParser, Object aContext,\r
+        StringBuffer aDestination, TALLogger aLogger, Map aTemplateContext,\r
+        TemplateLibrary aLibrary) throws TemplateProcessingException {\r
+\r
+      Object oldAttributes = aParser.evaluatePseudoVariable(aContext, "tagattributes");\r
+      aParser.processPseudoAssignment(aContext, "tagattributes", Collections.unmodifiableMap(fixedAttributes));\r
+\r
+      Object oldContent = aParser.evaluatePseudoVariable(aContext, "tagcontent");\r
+      aParser.processPseudoAssignment(aContext, "tagcontent", body.getPlainText());\r
+\r
+      try {\r
+        Iterator i;\r
+\r
+        i = definitions.iterator();\r
+        while (i.hasNext()) {\r
+          Definition d = (Definition) i.next();\r
+          aParser.processAssignment(aContext, d.getVariable(), d.getExpression());\r
+        }\r
+\r
+        if (condition == null || aParser.evaluateBooleanExpression(aContext, condition)) {\r
+          if (repeatExpression != null) {\r
+            i = aParser.evaluateListExpression(aContext, repeatExpression);\r
+\r
+            while (i.hasNext()) {\r
+              aParser.processDirectAssignment(aContext, repeatVariable, i.next());\r
+              innerProcess(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);\r
+            }\r
+          }\r
+          else {\r
+            innerProcess(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);\r
+          }\r
+        }\r
+      }\r
+      finally {\r
+        try {\r
+          aParser.processPseudoAssignment(aContext, "tagattributes", oldAttributes);\r
+          aParser.processPseudoAssignment(aContext, "tagcontent", oldContent);\r
+        }\r
+        catch (Throwable t) {\r
+        }\r
+      }\r
+    };\r
+\r
+    private void innerProcess(TALExpressionParser aParser, Object aContext,\r
+        StringBuffer aDestination, TALLogger aLogger, Map aTemplateContext, TemplateLibrary aLibrary)\r
+        throws TemplateProcessingException {\r
+\r
+      boolean omitTag = false;\r
+      StringBuffer content = aDestination;\r
+\r
+      if (omitTagExpression != null)\r
+        omitTag = aParser.evaluateBooleanExpression(aContext, omitTagExpression);\r
+\r
+      if (!omitTag) {\r
+        content = new StringBuffer();\r
+        Map generatedAttributes = new HashMap(fixedAttributes);\r
+\r
+        Iterator i = attributeModifiers.entrySet().iterator();\r
+        while (i.hasNext()) {\r
+          Map.Entry entry = (Map.Entry) i.next();\r
+\r
+          generatedAttributes.put(entry.getKey(), aParser.evaluateStringExpression(aContext, entry.getValue()));\r
+        }\r
+\r
+        aDestination.append("<");\r
+        aDestination.append(tag);\r
+\r
+        i = generatedAttributes.entrySet().iterator();\r
+        while (i.hasNext()) {\r
+          Map.Entry entry = (Map.Entry) i.next();\r
+          aDestination.append(" ");\r
+          aDestination.append(entry.getKey());\r
+          aDestination.append("=");\r
+          aDestination.append("\"");\r
+          aDestination.append(HTMLRoutines.encodeHTML( (String) entry.getValue()));\r
+          aDestination.append("\"");\r
+        }\r
+      }\r
+\r
+      try{\r
+        if (contentExpression != null) {\r
+          content.append(aParser.evaluateStringExpression(aContext, contentExpression));\r
+        }\r
+        else {\r
+          if (body != null) {\r
+            body.process(aParser, aContext, content, aLogger, aTemplateContext, aLibrary);\r
+          }\r
+        }\r
+        if (!omitTag) {\r
+          if (content.length()==0) {\r
+            aDestination.append(" />");\r
+          }\r
+          else {\r
+            aDestination.append(">");\r
+            aDestination.append(content);\r
+            aDestination.append("</");\r
+            aDestination.append(tag);\r
+            aDestination.append(">");\r
+          }\r
+        }\r
+      }\r
+      catch (Throwable t) {\r
+        if (!omitTag) {\r
+          aDestination.append(content);\r
+        }\r
+\r
+        if (t instanceof TemplateProcessingException) {\r
+          throw (TemplateProcessingException) t;\r
+        }\r
+        else if (t instanceof RuntimeException) {\r
+          throw (RuntimeException) t;\r
+        }\r
+        else throw new TemplateProcessingException(t.toString());\r
+      }\r
+    }\r
+  }\r
+}\r
diff --git a/source/mir/generator/tal/template/MacroTemplateNodeLibrary.java b/source/mir/generator/tal/template/MacroTemplateNodeLibrary.java
new file mode 100755 (executable)
index 0000000..1310c7b
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.generator.tal.template;
+
+import java.util.Map;
+import java.util.Iterator;
+import java.util.List;
+import java.util.HashMap;
+
+import mir.generator.tal.interfaces.TALExpressionParser;
+import mir.generator.tal.interfaces.TALLogger;
+import mir.util.xml.XMLName;
+import mir.util.xml.XMLParserExc;
+import mir.util.xml.XMLReaderTool;
+import mir.util.StringRoutines;
+import mir.util.HTMLRoutines;
+
+public class MacroTemplateNodeLibrary implements TemplateNodeLibrary {
+  /** {@inheritDoc} */
+  private static final String DEFINE_MACRO_ATTRIBUTE = "define-macro";
+  private static final String USE_MACRO_ATTRIBUTE = "use-macro";
+  private static final String DEFINE_SLOT_ATTRIBUTE = "define-slot";
+  private static final String FILL_SLOT_ATTRIBUTE = "fill-macro";
+
+  public static final String MACRO_DEFINITIONS_KEY = "$" + MacroTemplateNodeLibrary.class.getName() + "$macro_definitions";
+  public static final String ORPHANED_SLOTS_KEY = "$" + MacroTemplateNodeLibrary.class.getName() + "$macro_definitions";
+
+  private String prefix;
+  private String uri;
+
+
+  private boolean isOurTag(XMLName aName) {
+    return prefix.equals(aName.getPrefix()) || uri.equals(aName.getNamespaceURI());
+  }
+
+  public MacroTemplateNodeLibrary(String aPrefix, String aUri) {
+    prefix = aPrefix;
+    uri = aUri;
+  }
+
+  public TemplateNode constructTemplateNode(TALExpressionParser anExpressionParser, XMLName aTag, Map anAttributes,
+      TemplateNode aChildTemplateNode, Map aTemplateContext) throws XMLParserExc {
+
+    StringBuffer prefix = new StringBuffer();
+    boolean useSurroundingTag = !(isOurTag(aTag));
+
+    prefix.append("<").append(XMLReaderTool.normalizeXMLName(aTag));
+    String suffix = "</"+XMLReaderTool.normalizeXMLName(aTag)+">";
+
+    String macroDefinition = null;
+    String slotDefinition = null;
+    String slotFill = null;
+    Object macroCallExpression = null;
+
+    Iterator i = anAttributes.entrySet().iterator();
+
+    while (i.hasNext()) {
+      Map.Entry entry = (Map.Entry) i.next();
+      XMLName name = (XMLName) entry.getKey();
+
+      if (!isOurTag(name)) {
+        prefix.append(" ").append(XMLReaderTool.normalizeXMLName(name));
+        prefix.append("=\"").append(HTMLRoutines.encodeHTML( (String) entry.getValue())).append('"');
+      }
+      else {
+        if (name.getLocalName().equalsIgnoreCase(DEFINE_MACRO_ATTRIBUTE)) {
+          macroDefinition = (String) entry.getValue();
+        }
+        else if (name.getLocalName().equalsIgnoreCase(USE_MACRO_ATTRIBUTE)) {
+          macroCallExpression = anExpressionParser.preparseStringExpression((String) entry.getValue());
+        }
+        else if (name.getLocalName().equalsIgnoreCase(DEFINE_SLOT_ATTRIBUTE)) {
+          slotDefinition = (String) entry.getValue();
+        }
+        else if (name.getLocalName().equalsIgnoreCase(FILL_SLOT_ATTRIBUTE)) {
+          slotFill = (String) entry.getValue();
+        }
+      }
+    }
+    prefix.append(">");
+
+    MacroTemplateNode result;
+    if (useSurroundingTag) {
+      result = new MacroTemplateNode(aChildTemplateNode, prefix.toString(), suffix, slotDefinition, slotFill);
+    }
+    else {
+      result = new MacroTemplateNode(aChildTemplateNode, "", "", slotDefinition, slotFill);
+    }
+
+    if (macroCallExpression!=null) {
+      result.setMacroCall(macroCallExpression);
+    }
+
+    if (macroDefinition!=null) {
+      macroDefinition = macroDefinition.trim();
+      if (macroDefinition.length()==0) {
+        throw new XMLParserExc("Empty macro name");
+      }
+
+      Map definitions = (Map) aTemplateContext.get(MACRO_DEFINITIONS_KEY);
+      if (definitions==null) {
+        definitions=new HashMap();
+        aTemplateContext.put(MACRO_DEFINITIONS_KEY, definitions);
+      }
+
+      if (definitions.containsKey(macroDefinition)) {
+        throw new XMLParserExc("Duplicate macro name: " + macroDefinition);
+      }
+
+      definitions.put(macroDefinition, result);
+
+      Map slots = (Map) aTemplateContext.get(ORPHANED_SLOTS_KEY);
+      if (slots!=null) {
+      }
+    }
+
+    return result;
+  }
+
+  private class MacroTemplateNode implements TemplateNode {
+    private TemplateNode childNode;
+    private String prefix;
+    private String suffix;
+
+    private Object macroCallTemplateExpression = null;
+
+    private String slotDefinition;
+    private String slotFill;
+
+    public MacroTemplateNode(TemplateNode aChildNode, String aPrefix, String aSuffix,
+        String aSlotDefinition, String aSlotFill) {
+      childNode = aChildNode;
+      prefix = aPrefix;
+      suffix = aSuffix;
+
+      slotDefinition = aSlotDefinition;
+      slotFill = aSlotFill;
+    }
+
+    public void setMacroCall(Object anExpression) {
+      macroCallTemplateExpression = anExpression;
+    }
+
+    /** {@inheritDoc} */
+    public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination,
+        TALLogger aLogger, Map aTemplateContext, TemplateLibrary aLibrary) throws TemplateProcessingException {
+
+      if (macroCallTemplateExpression!=null) {
+        String macroPath = aParser.evaluateStringExpression(aContext, macroCallTemplateExpression);
+        List parts = StringRoutines.separateString(macroPath, "#");
+        if (parts.size()!=2) {
+          throw new TemplateProcessingException("Invalid macro path '" + macroPath + "'");
+        }
+
+        Template template = aLibrary.lookupTemplate((String) parts.get(0));
+        Map definitions = (Map) template.getContext().get(MACRO_DEFINITIONS_KEY);
+        if (template==null) {
+          throw new TemplateProcessingException("Cannot find template '" + (String) parts.get(0) + "'");
+        }
+        if (definitions==null || !definitions.containsKey(parts.get(1))) {
+          throw new TemplateProcessingException("No macro '"+(String) parts.get(1)+"' found in template '" + (String) parts.get(0) + "'");
+        }
+
+        MacroTemplateNode macro = (MacroTemplateNode) definitions.get(parts.get(1));
+
+        macro.process(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);
+      }
+      else {
+        aDestination.append(prefix);
+
+        childNode.process(aParser, aContext, aDestination, aLogger, aTemplateContext, aLibrary);
+        aDestination.append(suffix);
+      }
+    }
+
+    public String getPlainText() {
+      return childNode.getPlainText();
+    }
+  }
+}
index 85da086..617d45d 100755 (executable)
  */\r
 package mir.generator.tal.template;\r
 \r
+import java.util.Map;\r
+\r
 import mir.generator.tal.interfaces.TALExpressionParser;\r
 import mir.generator.tal.interfaces.TALLogger;\r
 \r
-public class PlainTextTemplateNode\r
-    implements TemplateNode {\r
-  private String text;\r
+/**\r
+ * Simple <code>TemplateNode</code> that just outputs a fixed\r
+ * piece of allText.\r
+ */\r
+public class PlainTextTemplateNode implements TemplateNode {\r
+  private String allText;\r
+  private String plainText;\r
 \r
   public PlainTextTemplateNode() {\r
-    this("");\r
+    this("", "");\r
   }\r
 \r
-  public PlainTextTemplateNode(String aText) {\r
-    text = aText;\r
+  public PlainTextTemplateNode(String aText, String aPlainText) {\r
+    allText = aText;\r
+    plainText = aPlainText;\r
   }\r
 \r
+  /** Appends text at the end */\r
   public void appendText(String aText) {\r
-    text = text + aText;\r
+    allText = allText + aText;\r
+  }\r
+\r
+  /** Appends allText at the end */\r
+  public void appendPlainText(String aText) {\r
+    plainText = plainText + aText;\r
+  }\r
+\r
+  public String getText() {\r
+    return allText;\r
   }\r
 \r
-  protected String getText() {\r
-    return text;\r
+  public String getPlainText() {\r
+    return plainText;\r
   }\r
 \r
-  public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination, TALLogger aLogger) throws TemplateProcessingException {\r
-    aDestination.append(text);\r
+  public void process(TALExpressionParser aParser, Object aContext,\r
+      StringBuffer aDestination, TALLogger aLogger,\r
+      Map aTemplateContext, TemplateLibrary aLibrary) throws TemplateProcessingException {\r
+    aDestination.append(allText);\r
   }\r
 }\r
diff --git a/source/mir/generator/tal/template/TALBasicTemplateNodeLibrary.java b/source/mir/generator/tal/template/TALBasicTemplateNodeLibrary.java
deleted file mode 100755 (executable)
index fbb1f45..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*\r
- * Copyright (C) 2001, 2002 The Mir-coders group\r
- *\r
- * This file is part of Mir.\r
- *\r
- * Mir is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Mir is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with Mir; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * In addition, as a special exception, The Mir-coders gives permission to link\r
- * the code of this program with  any library licensed under the Apache Software License,\r
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
- * (or with modified versions of the above that use the same license as the above),\r
- * and distribute linked combinations including the two.  You must obey the\r
- * GNU General Public License in all respects for all of the code used other than\r
- * the above mentioned libraries.  If you modify this file, you may extend this\r
- * exception to your version of the file, but you are not obligated to do so.\r
- * If you do not wish to do so, delete this exception statement from your version.\r
- */\r
-\r
-package mir.generator.tal.template;\r
-\r
-import java.util.Map;\r
-import java.util.List;\r
-import java.util.HashMap;\r
-import java.util.Vector;\r
-import java.util.Iterator;\r
-\r
-import mir.generator.tal.interfaces.TALExpressionParser;\r
-import mir.generator.tal.interfaces.TALLogger;\r
-import mir.util.HTMLRoutines;\r
-import mir.util.StringRoutines;\r
-import mir.util.xml.XMLName;\r
-import mir.util.xml.XMLParserExc;\r
-import mir.util.xml.XMLReaderTool;\r
-\r
-public class TALBasicTemplateNodeLibrary implements TALTemplateNodeLibrary {\r
-  private String prefix;\r
-  private String uri;\r
-\r
-  private boolean isOurTag(XMLName aName) {\r
-    return prefix.equals(aName.getPrefix()) || uri.equals(aName.getNamespaceURI());\r
-  }\r
-\r
-  public TALBasicTemplateNodeLibrary(String aPrefix, String aUri) {\r
-    prefix = aPrefix;\r
-    uri = aUri;\r
-  }\r
-\r
-  private static final String CONDITION_ATTRIBUTE = "condition";\r
-  private static final String REPEAT_ATTRIBUTE = "repeat";\r
-  private static final String CONTENT_ATTRIBUTE = "content";\r
-  private static final String ERROR_ATTRIBUTE = "on-error";\r
-  private static final String REPLACE_ATTRIBUTE = "replace";\r
-  private static final String DEFINITION_ATTRIBUTE = "define";\r
-  private static final String OMITTAG_ATTRIBUTE = "omit-tag";\r
-  private static final String ATTRIBUTE_ATTRIBUTE = "attributes";\r
-\r
-  public TemplateNode constructTemplateNode(TALExpressionParser aParser, XMLName aTag, Map anAttributes, TemplateNode aChildTemplateNode) throws XMLParserExc {\r
-    TALBasicTemplateNode result = new TALBasicTemplateNode(XMLReaderTool.normalizeXMLName(aTag));\r
-    result.setBody(aChildTemplateNode);\r
-\r
-    if (isOurTag(aTag))\r
-      result.setOmitTag(aParser.preparseTRUE());\r
-\r
-    Iterator i = anAttributes.entrySet().iterator();\r
-    while (i.hasNext()) {\r
-      Map.Entry entry = (Map.Entry) i.next();\r
-      XMLName name = (XMLName) entry.getKey();\r
-\r
-      if (!isOurTag(name)) {\r
-        result.addFixedAttribute(XMLReaderTool.normalizeXMLName(name), (String) entry.getValue());\r
-      }\r
-      else {\r
-        if (name.getLocalName().equalsIgnoreCase(DEFINITION_ATTRIBUTE)) {\r
-          List definitions = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\');\r
-\r
-          Iterator j = definitions.iterator();\r
-          while (j.hasNext())\r
-          {\r
-            List parts = StringRoutines.separateString((String) j.next(), " ");\r
-\r
-            if (parts.size()==2) {\r
-              result.addDefinition(aParser.preparseReferenceExpression((String) parts.get(0)), aParser.preparseExpression((String) parts.get(1)));\r
-            }\r
-          }\r
-        }\r
-        else if (name.getLocalName().equalsIgnoreCase(CONDITION_ATTRIBUTE)) {\r
-          result.setCondition(aParser.preparseBooleanExpression((String) entry.getValue()));\r
-        }\r
-        else if (name.getLocalName().equalsIgnoreCase(CONTENT_ATTRIBUTE)) {\r
-          result.setContent(aParser.preparseStringExpression((String) entry.getValue()));\r
-        }\r
-        else if (name.getLocalName().equalsIgnoreCase(ERROR_ATTRIBUTE)) {\r
-          result.setError(aParser.preparseStringExpression((String) entry.getValue()));\r
-        }\r
-        else if (name.getLocalName().equalsIgnoreCase(OMITTAG_ATTRIBUTE)) {\r
-          if (((String) entry.getValue()).trim().length()==0)\r
-            result.setOmitTag(aParser.preparseTRUE());\r
-          else\r
-            result.setOmitTag(aParser.preparseBooleanExpression((String) entry.getValue()));\r
-        }\r
-        else if (name.getLocalName().equalsIgnoreCase(REPLACE_ATTRIBUTE)) {\r
-          result.setOmitTag(aParser.preparseTRUE());\r
-          result.setContent(aParser.preparseStringExpression((String) entry.getValue()));\r
-        }\r
-        else if (name.getLocalName().equalsIgnoreCase(REPEAT_ATTRIBUTE)) {\r
-          List parts = StringRoutines.separateString((String) entry.getValue(), " ");\r
-\r
-          if (parts.size()==2) {\r
-            result.setRepeat(aParser.preparseReferenceExpression((String) parts.get(0)), aParser.preparseExpression((String) parts.get(1)));\r
-          }\r
-        }\r
-        else if (name.getLocalName().equalsIgnoreCase(ATTRIBUTE_ATTRIBUTE)) {\r
-          List attributes = StringRoutines.splitStringWithEscape((String) entry.getValue(), ';', '\\');\r
-\r
-          Iterator j = attributes.iterator();\r
-          while (j.hasNext()) {\r
-            String value = (String) j.next();\r
-            List parts = StringRoutines.separateString(value, " ");\r
-\r
-            if (parts.size()==2) {\r
-              result.addModifiedAttribute((String) parts.get(0), aParser.preparseExpression((String) parts.get(1)));\r
-            }\r
-            else {\r
-              throw new XMLParserExc(ATTRIBUTE_ATTRIBUTE + " tag should have exactly 2 parts ("+value+")");\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
-    return result;\r
-  }\r
-\r
-  public static class TALBasicTemplateNode implements TemplateNode {\r
-    private String tag;\r
-    private Map fixedAttributes;\r
-    private Map attributeModifiers;\r
-\r
-    private List definitions;\r
-    private Object condition;\r
-\r
-    private Object repeatVariable;\r
-    private Object repeatExpression;\r
-    private Object contentExpression;\r
-    private Object omitTagExpression;\r
-    private Object errorExpression;\r
-\r
-    private TemplateNode body;\r
-\r
-    public TALBasicTemplateNode(String aTag) {\r
-      tag = aTag;\r
-\r
-      fixedAttributes = new HashMap();\r
-      attributeModifiers = new HashMap();\r
-\r
-      definitions = new Vector();\r
-      condition = null;\r
-\r
-      repeatVariable = null;\r
-      repeatExpression = null;\r
-      contentExpression = null;\r
-      omitTagExpression = null;\r
-\r
-      body = null;\r
-    }\r
-\r
-    public void setBody(TemplateNode aBody) {\r
-      body = aBody;\r
-    }\r
-\r
-    public void addFixedAttribute(String aKey, String aValue) {\r
-      fixedAttributes.put(aKey, aValue);\r
-    }\r
-\r
-    public void addModifiedAttribute(String aKey, Object aValue) {\r
-      attributeModifiers.put(aKey, aValue);\r
-    }\r
-\r
-    public void addDefinition(Object aKey, Object aValue) {\r
-      definitions.add(new Definition(aKey, aValue));\r
-    }\r
-\r
-    public void setCondition(Object aCondition) {\r
-      condition = aCondition;\r
-    }\r
-\r
-    public void setRepeat(Object aRepeatVariable, Object aRepeatExpression) {\r
-      repeatVariable = aRepeatVariable;\r
-      repeatExpression = aRepeatExpression;\r
-    }\r
-\r
-    public void setContent(Object aContentExpression) {\r
-      contentExpression = aContentExpression;\r
-    }\r
-\r
-    public void setOmitTag(Object anOmitTagExpression) {\r
-      omitTagExpression = anOmitTagExpression;\r
-    }\r
-\r
-    public void setError(Object anErrorExpression) {\r
-      errorExpression = anErrorExpression;\r
-    }\r
-\r
-    public static class Definition {\r
-      private Object variable;\r
-      private Object expression;\r
-\r
-      public Definition(Object aVariable, Object anExpression) {\r
-        variable = aVariable;\r
-        expression = anExpression;\r
-      }\r
-\r
-      public Object getVariable() {\r
-        return variable;\r
-      }\r
-\r
-      public Object getExpression() {\r
-        return expression;\r
-      }\r
-    }\r
-\r
-    public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination, TALLogger aLogger) throws TemplateProcessingException {\r
-      if (errorExpression != null) {\r
-        StringBuffer destination = new StringBuffer();\r
-\r
-        try {\r
-          outerProcess(aParser, aContext, aDestination, aLogger);\r
-        }\r
-        catch (Throwable t) {\r
-          try {\r
-            destination.delete(0, destination.length());\r
-            aParser.processPseudoAssignment(aContext, "exception", t);\r
-            destination.append(aParser.evaluateStringExpression(aContext, errorExpression));\r
-          }\r
-          catch (Throwable s) {\r
-            throw new TemplateProcessingException(s);\r
-          }\r
-        }\r
-        finally {\r
-          aDestination.append(destination);\r
-        }\r
-      }\r
-      else {\r
-        outerProcess(aParser, aContext, aDestination, aLogger);\r
-      }\r
-    }\r
-\r
-    public void outerProcess(TALExpressionParser aParser, Object aContext, StringBuffer aDestination, TALLogger aLogger) throws TemplateProcessingException {\r
-      Iterator i;\r
-\r
-      i = definitions.iterator();\r
-      while (i.hasNext()) {\r
-        Definition d = (Definition) i.next();\r
-        aParser.processAssignment(aContext, d.getVariable(), d.getExpression());\r
-      }\r
-\r
-      if (condition == null || aParser.evaluateBooleanExpression(aContext, condition)) {\r
-        if (repeatExpression != null) {\r
-          i = aParser.evaluateListExpression(aContext, repeatExpression);\r
-\r
-          while (i.hasNext()) {\r
-            aParser.processDirectAssignment(aContext, repeatVariable, i.next());\r
-            innerProcess(aParser, aContext, aDestination, aLogger);\r
-          }\r
-        }\r
-        else {\r
-          innerProcess(aParser, aContext, aDestination, aLogger);\r
-        }\r
-      }\r
-    };\r
-\r
-    private void innerProcess(TALExpressionParser aParser, Object aContext, StringBuffer aDestination, TALLogger aLogger)\r
-        throws TemplateProcessingException {\r
-\r
-      boolean omitTag = false;\r
-\r
-      if (omitTagExpression != null)\r
-        omitTag = aParser.evaluateBooleanExpression(aContext, omitTagExpression);\r
-\r
-      if (!omitTag) {\r
-        Map generatedAttributes = new HashMap(fixedAttributes);\r
-\r
-        Iterator i = attributeModifiers.entrySet().iterator();\r
-        while (i.hasNext()) {\r
-          Map.Entry entry = (Map.Entry) i.next();\r
-\r
-          generatedAttributes.put(entry.getKey(), aParser.evaluateStringExpression(aContext, entry.getValue()));\r
-        }\r
-\r
-        aDestination.append("<");\r
-        aDestination.append(tag);\r
-\r
-        i = generatedAttributes.entrySet().iterator();\r
-        while (i.hasNext()) {\r
-          Map.Entry entry = (Map.Entry) i.next();\r
-          aDestination.append(" ");\r
-          aDestination.append(entry.getKey());\r
-          aDestination.append("=");\r
-          aDestination.append("\"");\r
-          aDestination.append(HTMLRoutines.encodeHTML( (String) entry.getValue()));\r
-          aDestination.append("\"");\r
-        }\r
-        aDestination.append(">");\r
-      }\r
-\r
-      if (contentExpression != null) {\r
-        aDestination.append(aParser.evaluateStringExpression(aContext, contentExpression));\r
-      }\r
-      else {\r
-        if (body != null) {\r
-          body.process(aParser, aContext, aDestination, aLogger);\r
-        }\r
-      }\r
-      if (!omitTag) {\r
-        aDestination.append("</");\r
-        aDestination.append(tag);\r
-        aDestination.append(">");\r
-      }\r
-    }\r
-  }\r
-}\r
diff --git a/source/mir/generator/tal/template/TALTemplate.java b/source/mir/generator/tal/template/TALTemplate.java
deleted file mode 100755 (executable)
index eb56e41..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*\r
- * Copyright (C) 2001, 2002 The Mir-coders group\r
- *\r
- * This file is part of Mir.\r
- *\r
- * Mir is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Mir is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with Mir; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * In addition, as a special exception, The Mir-coders gives permission to link\r
- * the code of this program with  any library licensed under the Apache Software License,\r
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
- * (or with modified versions of the above that use the same license as the above),\r
- * and distribute linked combinations including the two.  You must obey the\r
- * GNU General Public License in all respects for all of the code used other than\r
- * the above mentioned libraries.  If you modify this file, you may extend this\r
- * exception to your version of the file, but you are not obligated to do so.\r
- * If you do not wish to do so, delete this exception statement from your version.\r
- */\r
-package mir.generator.tal.template;\r
-\r
-import java.io.PrintWriter;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Vector;\r
-\r
-import mir.generator.tal.interfaces.TALExpressionParser;\r
-import mir.generator.tal.interfaces.TALLogger;\r
-import mir.util.HTMLRoutines;\r
-\r
-/**\r
- *\r
- *\r
- *\r
- * @see <a href="http://dev.zope.org/Wikis/DevSite/Projects/ZPT/TAL%20Specification%201.4">TAL Spec</a>\r
- */\r
-\r
-public class TALTemplate {\r
-  private TemplateNode rootNode;\r
-  private TALExpressionParser parser;\r
-\r
-  public TALTemplate(TALExpressionParser aParser, TemplateNode aRootNode) {\r
-    rootNode = aRootNode;\r
-    parser = aParser;\r
-  }\r
-\r
-  public void processTemplate(Object aContext, PrintWriter aDestination, TALLogger aLogger) throws TemplateProcessingException {\r
-    StringBuffer output = new StringBuffer();\r
-\r
-    aLogger.debug("TALTemplate", "processing rootnode");\r
-    rootNode.process(parser, aContext, output, aLogger);\r
-    aLogger.debug("TALTemplate", "done processing rootnode");\r
-    aDestination.print(output);\r
-  }\r
-\r
-}
\ No newline at end of file
diff --git a/source/mir/generator/tal/template/TALTemplateNodeLibrary.java b/source/mir/generator/tal/template/TALTemplateNodeLibrary.java
deleted file mode 100755 (executable)
index 2d1aab8..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*\r
- * Copyright (C) 2001, 2002 The Mir-coders group\r
- *\r
- * This file is part of Mir.\r
- *\r
- * Mir is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Mir is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with Mir; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * In addition, as a special exception, The Mir-coders gives permission to link\r
- * the code of this program with  any library licensed under the Apache Software License,\r
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
- * (or with modified versions of the above that use the same license as the above),\r
- * and distribute linked combinations including the two.  You must obey the\r
- * GNU General Public License in all respects for all of the code used other than\r
- * the above mentioned libraries.  If you modify this file, you may extend this\r
- * exception to your version of the file, but you are not obligated to do so.\r
- * If you do not wish to do so, delete this exception statement from your version.\r
- */\r
-package mir.generator.tal.template;\r
-\r
-import java.util.Map;\r
-\r
-import mir.util.xml.XMLName;\r
-import mir.util.xml.XMLParserExc;\r
-import mir.generator.tal.interfaces.TALExpressionParser;\r
-\r
-public interface TALTemplateNodeLibrary {\r
-  public TemplateNode constructTemplateNode(TALExpressionParser anExpressionParser, XMLName aTag, Map anAttributes, TemplateNode aChildTemplateNode) throws XMLParserExc;\r
-}\r
diff --git a/source/mir/generator/tal/template/Template.java b/source/mir/generator/tal/template/Template.java
new file mode 100755 (executable)
index 0000000..e890c05
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.generator.tal.template;\r
+\r
+import java.io.PrintWriter;\r
+import java.util.Map;\r
+\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+import mir.generator.tal.interfaces.TALLogger;\r
+\r
+/**\r
+ * @see <a href="http://dev.zope.org/Wikis/DevSite/Projects/ZPT/TAL%20Specification%201.4">TAL Spec</a>\r
+ */\r
+\r
+public class Template {\r
+  private TemplateNode rootNode;\r
+  private TALExpressionParser parser;\r
+  private Map context;\r
+\r
+  public Template(TALExpressionParser aParser, TemplateNode aRootNode, Map aTemplateContext) {\r
+    rootNode = aRootNode;\r
+    parser = aParser;\r
+    context = aTemplateContext;\r
+  }\r
+\r
+  /** get this template's context */\r
+  public Map getContext() {\r
+    return context;\r
+  }\r
+\r
+  public void process(Object aContext, PrintWriter aDestination,\r
+      TALLogger aLogger, TemplateLibrary aLibrary) throws TemplateProcessingException {\r
+    StringBuffer output = new StringBuffer();\r
+\r
+    aLogger.debug("Template", "processing rootnode");\r
+    rootNode.process(parser, aContext, output, aLogger, context, aLibrary);\r
+    aLogger.debug("Template", "done processing rootnode");\r
+    aDestination.print(output);\r
+  }\r
+\r
+}
\ No newline at end of file
diff --git a/source/mir/generator/tal/template/TemplateLibrary.java b/source/mir/generator/tal/template/TemplateLibrary.java
new file mode 100755 (executable)
index 0000000..e558c89
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.generator.tal.template;
+
+/**
+ * A <code>TemplateLibrary</code> offers access to a set of {@link Template}s.
+ * Templates can be looked up by name.
+ */
+public interface TemplateLibrary {
+  /**
+   * Looks up a Template based on a name
+   */
+  public Template lookupTemplate(String aTemplateName) throws TemplateProcessingException;
+}
index 9b62215..824552d 100755 (executable)
  */\r
 package mir.generator.tal.template;\r
 \r
+import java.util.Map;\r
+\r
 import mir.generator.tal.interfaces.TALExpressionParser;\r
 import mir.generator.tal.interfaces.TALLogger;\r
 \r
+/**\r
+ * A {@link Template} consists of a chain of <code>TemplateNodes</code>.\r
+ */\r
 public interface TemplateNode {\r
-  public void process(TALExpressionParser aParser, Object aContext, StringBuffer aDestination, TALLogger aLogger) throws TemplateProcessingException;\r
+  /**\r
+   */\r
+  public void process(\r
+      TALExpressionParser aParser,\r
+      Object aContext,\r
+      StringBuffer aDestination,\r
+      TALLogger aLogger,\r
+      Map aTemplateContext,\r
+      TemplateLibrary aTemplateLibrary) throws TemplateProcessingException;\r
+\r
+  public String getPlainText();\r
 }\r
diff --git a/source/mir/generator/tal/template/TemplateNodeLibrary.java b/source/mir/generator/tal/template/TemplateNodeLibrary.java
new file mode 100755 (executable)
index 0000000..bdb8545
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.generator.tal.template;\r
+\r
+import java.util.Map;\r
+\r
+import mir.util.xml.XMLName;\r
+import mir.util.xml.XMLParserExc;\r
+import mir.generator.tal.interfaces.TALExpressionParser;\r
+\r
+public interface TemplateNodeLibrary {\r
+  /**\r
+   * Construct a {@link TemplateNode} based on the tag and attributes given.\r
+   *\r
+   * @param anExpressionParser\r
+   * @param aTag\r
+   * @param anAttributes\r
+   * @param aChildTemplateNode\r
+   */\r
+  public TemplateNode constructTemplateNode(TALExpressionParser anExpressionParser,\r
+      XMLName aTag, Map anAttributes, TemplateNode aChildTemplateNode, Map aTemplateContext) throws XMLParserExc;\r
+}\r
diff --git a/source/mir/generator/tal/template/TemplateNodeLibraryRegistry.java b/source/mir/generator/tal/template/TemplateNodeLibraryRegistry.java
new file mode 100755 (executable)
index 0000000..a67e371
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.generator.tal.template;
+
+public interface TemplateNodeLibraryRegistry {
+  public TemplateNodeLibrary findLibraryForUrl(String aUrl);
+  public TemplateNodeLibrary findLibraryForPrefix(String aPrefix);
+}
index da7bb1b..19a70b4 100755 (executable)
@@ -45,4 +45,8 @@ public class TemplateProcessingException extends Exception {
   public TemplateProcessingException(String aMessage) {\r
     this(aMessage, null);\r
   }\r
+\r
+  public Throwable getCause() {\r
+    return cause;\r
+  }\r
 }\r
diff --git a/source/mir/log/Log.java b/source/mir/log/Log.java
deleted file mode 100755 (executable)
index 17fec30..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
- * If you do not wish to do so, delete this exception statement from your version.
- */
-
-package mir.log;
-
-import mir.config.MirPropertiesConfiguration;
-import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
-
-public class Log {
-
-  private static Logger myLogger;
-
-  static {
-    try {
-      String loggerClass = MirPropertiesConfiguration.instance().getString("Log.LogClass");
-      myLogger = (Logger) Class.forName(loggerClass).newInstance();
-    }
-    catch (java.lang.ClassNotFoundException cnfe) {
-      System.err.println("Log was not able to initialize: class not found");
-      cnfe.printStackTrace(System.err);
-    }
-    catch (java.lang.InstantiationException ie) {
-      System.err.println(
-          "Log was not able to initialize: could not initialize class");
-      ie.printStackTrace(System.err);
-    }
-    catch (java.lang.IllegalAccessException iae) {
-      System.err.println("Log was not able to initialize: illegal access");
-      iae.printStackTrace(System.err);
-    }
-    catch (PropertiesConfigExc e) {
-      e.printStackTrace(System.err);
-    }
-  }
-
-  public static void debug(Object o, String s) {
-    myLogger.debug(o, s);
-  }
-
-  public static void info(Object o, String s) {
-    myLogger.info(o, s);
-  }
-
-  public static void warn(Object o, String s) {
-    myLogger.warn(o, s);
-  }
-
-  public static void error(Object o, String s) {
-    myLogger.error(o, s);
-  }
-
-  public static void fatal(Object o, String s) {
-    myLogger.fatal(o, s);
-  }
-}
index 47dc7db..46d052a 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 
@@ -38,4 +38,6 @@ public interface Logger {
   public void warn( Object o, String s);
   public void error( Object o, String s);
   public void fatal( Object o, String s);
+
+  public void reload() throws LoggerExc, LoggerFailure;
 }
diff --git a/source/mir/log/LoggerEngine.java b/source/mir/log/LoggerEngine.java
new file mode 100755 (executable)
index 0000000..9073595
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+
+package mir.log;
+
+import mir.config.MirPropertiesConfiguration;
+
+public class LoggerEngine {
+  private static Logger loggerInstance;
+
+  static {
+    try {
+      String loggerClass = MirPropertiesConfiguration.instance().getString("Log.LogClass");
+      loggerInstance = (Logger) Class.forName(loggerClass).newInstance();
+    }
+    catch (java.lang.ClassNotFoundException cnfe) {
+      System.err.println("LoggerEngine was not able to initialize: class not found");
+      cnfe.printStackTrace(System.err);
+    }
+    catch (java.lang.InstantiationException ie) {
+      System.err.println(
+          "LoggerEngine was not able to initialize: could not initialize class");
+      ie.printStackTrace(System.err);
+    }
+    catch (java.lang.IllegalAccessException iae) {
+      System.err.println("LoggerEngine was not able to initialize: illegal access");
+      iae.printStackTrace(System.err);
+    }
+  }
+
+  public static void debug(Object o, String s) {
+    loggerInstance.debug(o, s);
+  }
+
+  public static void info(Object o, String s) {
+    loggerInstance.info(o, s);
+  }
+
+  public static void warn(Object o, String s) {
+    loggerInstance.warn(o, s);
+  }
+
+  public static void error(Object o, String s) {
+    loggerInstance.error(o, s);
+  }
+
+  public static void fatal(Object o, String s) {
+    loggerInstance.fatal(o, s);
+  }
+
+  public static void reload() throws LoggerExc, LoggerFailure {
+    loggerInstance.reload();
+  }
+}
diff --git a/source/mir/log/LoggerExc.java b/source/mir/log/LoggerExc.java
new file mode 100755 (executable)
index 0000000..10bfd70
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.log;
+
+import multex.Exc;
+
+public class LoggerExc extends Exc {
+  public LoggerExc(String aMessage) {
+    super(aMessage);
+  }
+}
diff --git a/source/mir/log/LoggerFailure.java b/source/mir/log/LoggerFailure.java
new file mode 100755 (executable)
index 0000000..f8d1b16
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.log;
+
+import multex.Failure;
+
+public class LoggerFailure extends Failure {
+
+  public LoggerFailure(String aMessage,Throwable aCause) {
+    super(aMessage, aCause);
+  }
+
+  public LoggerFailure(Throwable aCause) {
+    this (aCause.getMessage(), aCause);
+  }
+}
index 7853ef9..eb8db65 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 
@@ -45,23 +45,23 @@ public class LoggerWrapper {
   }
 
   public void debug( String aMessage ) {
-    Log.debug(object, aMessage);
+    LoggerEngine.debug(object, aMessage);
   };
 
   public void info( String aMessage ) {
-    Log.info(object, aMessage);
+    LoggerEngine.info(object, aMessage);
   };
 
   public void warn( String aMessage ) {
-    Log.warn(object, aMessage);
+    LoggerEngine.warn(object, aMessage);
   };
 
   public void error( String aMessage ) {
-    Log.error(object, aMessage);
+    LoggerEngine.error(object, aMessage);
   };
 
   public void fatal( String aMessage ) {
-    Log.fatal(object, aMessage);
+    LoggerEngine.fatal(object, aMessage);
   };
 
   public void message( int aType, String aMessage) {
diff --git a/source/mir/log/TestFramework.java b/source/mir/log/TestFramework.java
deleted file mode 100755 (executable)
index 48a7891..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
- * If you do not wish to do so, delete this exception statement from your version.
- */
-
-package mir.log;
-
-
-public class TestFramework {
-
-  public static void main(String[] args) {
-    TestFramework t = new TestFramework();
-
-    Log.info( TestFramework.class, "class");
-    Log.info( t, "object" );
-    Log.info( null, "lalala" );
-  }
-}
index 99ebed4..cd80fd8 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.log.log4j;
@@ -33,8 +33,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 import mir.config.MirPropertiesConfiguration;
-import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
-
+import mir.log.LoggerExc;
+import mir.log.LoggerFailure;
 import org.apache.log4j.Logger;
 import org.apache.log4j.PropertyConfigurator;
 
@@ -42,33 +42,53 @@ import org.apache.log4j.PropertyConfigurator;
 public class LoggerImpl implements mir.log.Logger {
   private static Map loggers = new HashMap();
 
-  public LoggerImpl() throws PropertiesConfigExc {
-    System.setProperty("log.home",
-        MirPropertiesConfiguration.instance().getStringWithHome("Log.Home"));
-    PropertyConfigurator.configure(
-        MirPropertiesConfiguration.instance().getStringWithHome("Log.log4j.ConfigurationFile").trim());
+  public LoggerImpl() throws LoggerExc {
+    reload();
   }
 
+  /** {@inheritDoc} */
   public void debug(Object o, String s) {
     this.getLogger(o).debug(s);
   }
 
+  /** {@inheritDoc} */
   public void info(Object o, String s) {
     this.getLogger(o).info(s);
   }
 
+  /** {@inheritDoc} */
   public void warn(Object o, String s) {
     this.getLogger(o).warn(s);
   }
 
+  /** {@inheritDoc} */
   public void error(Object o, String s) {
     this.getLogger(o).error(s);
   }
 
+  /** {@inheritDoc} */
   public void fatal(Object o, String s) {
     this.getLogger(o).fatal(s);
   }
 
+  /** {@inheritDoc} */
+  public void reload() throws LoggerExc, LoggerFailure {
+    try {
+      synchronized (loggers) {
+        System.setProperty("log.home",
+            MirPropertiesConfiguration.instance().getFile("Log.Home").getAbsolutePath());
+
+        PropertyConfigurator.configure(
+            MirPropertiesConfiguration.instance().getFile("Log.log4j.ConfigurationFile").getAbsolutePath());
+
+        loggers.clear();
+      }
+    }
+    catch (Throwable t) {
+      throw new LoggerFailure(t);
+    }
+  }
+
   private Logger getLogger(Object o) {
     String name;
     Logger l;
index 33a45f4..a77ab2e 100755 (executable)
 package  mir.media;
 
 import java.io.InputStream;
+import java.io.File;
 import java.util.List;
 
 import mir.entity.Entity;
+import mir.session.UploadedFile;
 
 /**
  * Interface for Media handling in Mir. All media handlers
@@ -79,90 +81,65 @@ import mir.entity.Entity;
  * ) and just override the things that need to be specific. see MediaHandlerAudio
  *
  * @author <mh@nadir.org>, the Mir-coders group
- * @version $Id: MediaHandler.java,v 1.1.2.2 2003/12/21 13:32:03 zapata Exp $
+ * @version $Id: MediaHandler.java,v 1.1.2.3 2004/11/21 22:07:13 zapata Exp $
  */
 
 public interface MediaHandler {
   /**
-   * 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 InputStream, a stream of 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
+   * Store the media content from an {@link UploadedFile}
    */
-  public void store(InputStream in, Entity ent, Entity mediaTypeEnt ) throws MediaExc, MediaFailure;
+  public void store(UploadedFile anUploadedFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure;
+
+  /**
+   * Store the media content from an input stream.
+   */
+  public void store(InputStream anInputStream, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure;
+
+  /**
+   * Store the media content from a file.
+   */
+  public void store(File aFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure;
+
+  /**
+   * Perform production related tasks for this media.  
+   */
+  public void produce(Entity aMedia, Entity aMediaType ) throws MediaExc, MediaFailure;
 
-  public void produce(Entity ent, Entity mediaTypeEnt ) throws MediaExc, MediaFailure;
   /**
    * Get's the media data from storage and returns it as an InputStream
    * 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 java.io.InputStream
-   * @see mir.entity.Entity
    */
-  public InputStream getMedia (Entity ent, Entity mediaTypeEnt) throws MediaExc, MediaFailure;
+  public InputStream getMedia (Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure;
 
   /**
    * 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 java.io.InputStream
-   * @see mir.entity.Entity
    */
-  public InputStream getThumbnail(Entity ent) throws MediaExc, MediaFailure;
+  public InputStream getThumbnail(Entity aMedia) throws MediaExc, MediaFailure;
 
 
   /**
-   *
-   * @param ent
-   * @return
-   * @throws MediaExc
-   * @throws MediaFailure
+   * Returns the mime-type of the media's thumbnail
    */
   public String getThumbnailMimeType(Entity aMediaEntity, Entity aMediaType) throws MediaExc, MediaFailure;
 
   /**
-   * 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 List getURL (Entity ent, Entity mediaTypeEnt) throws MediaExc, MediaFailure;
-
-        /**
    * 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 String getStoragePath () throws MediaExc, MediaFailure;
 
-        /**
+  /**
    * 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 String getIconStoragePath () throws MediaExc, MediaFailure;
 
@@ -174,8 +151,6 @@ public interface MediaHandler {
    * It is usually defined
    * in the configuration witch is accessible through the MirConfig
    * class.
-   * @return String, the base URL to the host.
-   * @see mir.misc.MirConfig
    */
   public String getPublishHost () throws MediaExc, MediaFailure;
 
@@ -185,8 +160,6 @@ public interface MediaHandler {
    * It is usually defined
    * in the configuration wich is accessible through the MirConfig
    * class.
-   * @return String, the icon filename.
-   * @see mir.misc.MirConfig
    */
   public String getBigIconName ();
 
@@ -197,8 +170,6 @@ public interface MediaHandler {
    * It is usually defined
    * in the configuration wich is accessible through the MirConfig
    * class.
-   * @return String, the icon filename.
-   * @see mir.misc.MirConfig
    */
   public String getTinyIconName ();
 
@@ -214,7 +185,7 @@ public interface MediaHandler {
    * media type is.
    * @return String
    */
-  public String getDescr (Entity mediaTypeEnt);
+  public String getDescr (Entity aMediaType);
 
 }
 
index 63299e4..688d951 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.misc;
@@ -39,28 +39,10 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
-
-import mir.config.MirPropertiesConfiguration;
-import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
-
 /**
  * Hilfsklasse zum Mergen von Template und Daten
  */
 public final class FileUtil {
-
-  private static String producerStorageRoot;
-
-
-  static {
-    try {
-      producerStorageRoot =
-          MirPropertiesConfiguration.instance().getString("Producer.StorageRoot");
-    }
-    catch (PropertiesConfigExc e) {
-      e.printStackTrace();
-    }
-  }
-
   /**
    * Privater Construktor to avoid accidental instantiation
    */
index 173f6ad..aea424b 100755 (executable)
@@ -52,13 +52,12 @@ import mir.storage.StorageObject;
 public class AbstractModule {
   protected StorageObject storage;
 
-  public void setStorage(StorageObject storage) {
-    this.storage = storage;
+  public AbstractModule(StorageObject aStorageObject) {
+    storage = aStorageObject;
   }
 
   /**
-   * Liefert das Standard-StorageObject zur?ck, mit dem das Module assoziiert ist.
-   * @return Standard-StorageObject
+   * Returns the storage object associated with this module
    */
   public StorageObject getStorageObject () {
     return storage;
diff --git a/source/mir/producer/BundleProducerNode.java b/source/mir/producer/BundleProducerNode.java
new file mode 100755 (executable)
index 0000000..f7f8cdb
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.producer;
+
+import java.util.Map;
+
+import mir.bundle.Bundle;
+import mir.log.LoggerWrapper;
+import mir.util.ParameterExpander;
+import mir.util.generator.BundleGeneratorFunction;
+import mircoders.global.MirGlobal;
+
+/**
+ * This producer node loads a bundle
+ */
+public class BundleProducerNode implements ProducerNode {
+  private String key;
+  private String bundleExpression;
+  private String languageExpression;
+
+  public BundleProducerNode(String aKey, String aBundleExpression) {
+    this (aKey, aBundleExpression, null);
+  }
+
+  public BundleProducerNode(String aKey, String aBundleExpression, String aLanguageExpression) {
+    bundleExpression = aBundleExpression;
+    languageExpression = aLanguageExpression;
+    key = aKey;
+  }
+
+  /** {@inheritDoc} */
+  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
+    try {
+      String bundle = ParameterExpander.expandExpression( aValueMap, bundleExpression );
+      String[] languages = new String[0];
+      if (languageExpression!=null)
+        languages = new String[] { ParameterExpander.expandExpression( aValueMap, languageExpression ) };
+
+      if (MirGlobal.config().getString("Producer.BundleCompatibility", "0").equals("1") &&
+          bundle.startsWith("bundles.")) {
+        bundle = "etc/bundles/" + bundle.substring("bundles.".length());
+      }
+
+      ParameterExpander.setValueForKey(
+          aValueMap, key, new BundleGeneratorFunction(
+              new Bundle[] { MirGlobal.getBundleFactory().getBundle( bundle, languages ) }
+          )
+      );
+    }
+    catch (Throwable t) {
+      aLogger.error("Failed to load bundle " + bundleExpression + " for language " +
+          languageExpression +  " into key " + key + ": " + t.getMessage());
+    }
+  };
+
+}
\ No newline at end of file
index 9f4db9e..63fe79e 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.producer;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
 
 import mir.log.LoggerWrapper;
 
@@ -40,7 +40,7 @@ public class CompositeProducerNode implements ProducerNode {
   private List subNodes;
 
   public CompositeProducerNode() {
-    subNodes = new Vector();
+    subNodes = new ArrayList();
   }
 
   public CompositeProducerNode(ProducerNode[] aSubNodes) {
index d4e823c..2eb3b08 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.producer;
@@ -39,10 +39,10 @@ import mir.util.ParameterExpander;
 public class DirCopyingProducerNode implements ProducerNode  {
   private String sourceExpression;
   private String destinationExpression;
-  private String sourceBasePath;
-  private String destinationBasePath;
+  private File sourceBasePath;
+  private File destinationBasePath;
 
-  public DirCopyingProducerNode(String aSourceBasePath, String aDestinationBasePath, String aSource, String aDestination) {
+  public DirCopyingProducerNode(File aSourceBasePath, File aDestinationBasePath, String aSource, String aDestination) {
     sourceBasePath = aSourceBasePath;
     destinationBasePath = aDestinationBasePath;
     sourceExpression = aSource;
@@ -52,8 +52,6 @@ public class DirCopyingProducerNode implements ProducerNode  {
   public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
     String source = "";
     String destination = "";
-    File sourceFile;
-    File destinationFile;
 
     try {
       source = ParameterExpander.expandExpression( aValueMap, sourceExpression );
index 50207c7..aa0bf41 100755 (executable)
@@ -33,12 +33,13 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
+import java.util.ArrayList;
 
 import mir.entity.adapter.EntityAdapterModel;
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
 import mir.util.ParameterExpander;
+import mir.util.StringRoutines;
 
 /**
  * <p>Title: EntityBatchingProducerNode</p>
@@ -60,7 +61,7 @@ public class EntityBatchingProducerNode implements ProducerNode {
   private String batchDataKey;
   private EntityAdapterModel model;
   private String mainTablePrefix;
-  private List extraTables;
+  private String extraTables;
   private String definition;
   private String whereClause;
   private String orderByClause;
@@ -76,7 +77,7 @@ public class EntityBatchingProducerNode implements ProducerNode {
         String aBatchInfoKey,
         EntityAdapterModel aModel,
         String aMainTablePrefix,
-        List   someExtraTables,
+        String someExtraTables,
         String aDefinition,
         String aWhereClause,
         String anOrderByClause,
@@ -103,7 +104,7 @@ public class EntityBatchingProducerNode implements ProducerNode {
     minNrEntitiesInFirstBatchExpression = aminNrEntitiesInFirstBatchExpression;
     nrBatchesToProcessExpression = aNrBatchesToProcessExpression;
   }
+
   protected boolean isAborted(Map aValueMap) {
     Object producerValue = aValueMap.get(NodedProducer.PRODUCER_KEY);
     return (
@@ -112,14 +113,12 @@ public class EntityBatchingProducerNode implements ProducerNode {
   }
 
   public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
-    Iterator browser;
     int nrEntities;
     int nrBatchesAfterFirst;
     int nrEntitiesInFirstBatch;
     int nrBatchesToProcess;
     List batchesData;
     int i;
-    int position;
     Map batchData;
     String expandedWhereClause;
     String expandedOrderByClause;
@@ -140,11 +139,13 @@ public class EntityBatchingProducerNode implements ProducerNode {
       nrEntitiesToSkip = ParameterExpander.evaluateIntegerExpression( aValueMap, nrEntitiesToSkipExpression);
       nrEntitiesPerBatch = ParameterExpander.evaluateIntegerExpression( aValueMap, nrEntitiesPerBatchExpression);
       minNrEntitiesInFirstBatch = ParameterExpander.evaluateIntegerExpression( aValueMap, minNrEntitiesInFirstBatchExpression);
+      List extraTableList = StringRoutines.splitString(ParameterExpander.expandExpression( aValueMap, extraTables).trim(), ",");
 
-      batchesData = new Vector();
-      batchLocations = new Vector();
+      batchesData = new ArrayList();
+      batchLocations = new ArrayList();
 
-      nrEntities = model.getMappingForName(definition).getStorage().getSize(mainTablePrefix, extraTables, expandedWhereClause)-nrEntitiesToSkip;
+      nrEntities = model.getMappingForName(definition).getStorage().getSize(
+          mainTablePrefix, extraTableList, expandedWhereClause)-nrEntitiesToSkip;
       nrEntitiesInFirstBatch = nrEntities % nrEntitiesPerBatch;
       while (nrEntitiesInFirstBatch<minNrEntitiesInFirstBatch && nrEntities-nrEntitiesInFirstBatch>=nrEntitiesPerBatch)
         nrEntitiesInFirstBatch = nrEntitiesInFirstBatch + nrEntitiesPerBatch;
@@ -196,9 +197,9 @@ public class EntityBatchingProducerNode implements ProducerNode {
           else
             batchData.put("next", null);
 
-          Iterator j = new EntityIteratorAdapter(mainTablePrefix, extraTables, expandedWhereClause, expandedOrderByClause,
+          Iterator j = new EntityIteratorAdapter(mainTablePrefix, extraTableList, expandedWhereClause, expandedOrderByClause,
                     location.nrEntities, model, definition, location.nrEntities, location.firstEntity);
-          List entities = new Vector();
+          List entities = new ArrayList();
 
           while (j.hasNext())
             entities.add(0, j.next());
index da7bd9e..ca4fef8 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.producer;
 
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 import mir.entity.adapter.EntityAdapterModel;
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
 import mir.util.ParameterExpander;
+import mir.util.StringRoutines;
 
 public class EntityEnumeratingProducerNode extends ProducerNodeDecorator {
   private String key;
   private EntityAdapterModel model;
   private String definition;
   private String mainTablePrefix;
-  private List extraTables;
+  private String extraTables;
   private String skip;
   private String limit;
   private String whereClause;
@@ -52,7 +52,7 @@ public class EntityEnumeratingProducerNode extends ProducerNodeDecorator {
   public EntityEnumeratingProducerNode(
               String aKey,
               EntityAdapterModel aModel, String aMainTablePrefix,
-              List someExtraTables, String aDefinition,
+              String anExtraTables, String aDefinition,
               String aWhereClause, String anOrderByClause,
               String aLimit, String aSkip,
               ProducerNode aSubNode) {
@@ -62,7 +62,7 @@ public class EntityEnumeratingProducerNode extends ProducerNodeDecorator {
     definition = aDefinition;
     key = aKey;
     mainTablePrefix=aMainTablePrefix;
-    extraTables=someExtraTables;
+    extraTables = anExtraTables;
     whereClause = aWhereClause;
     orderByClause = anOrderByClause;
 
@@ -76,7 +76,7 @@ public class EntityEnumeratingProducerNode extends ProducerNodeDecorator {
     try {
       browser = new EntityIteratorAdapter(
           mainTablePrefix,
-          extraTables,
+          StringRoutines.splitString(ParameterExpander.expandExpression( aValueMap, extraTables).trim(), ","),
           ParameterExpander.expandExpression( aValueMap, whereClause ),
           ParameterExpander.expandExpression( aValueMap, orderByClause ),
           100,
index 9b151d1..32e0d3a 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.producer;
 
-import java.util.List;
+import java.util.Collections;
 import java.util.Map;
-import java.util.Vector;
 
 import mir.entity.adapter.EntityAdapterModel;
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
 import mir.util.CachingRewindableIterator;
 import mir.util.ParameterExpander;
+import mir.util.StringRoutines;
 
 public class EntityListProducerNode extends ProducerNodeDecorator {
-  private String key;
+  private String keyExpression;
   private String whereClause;
   private String orderByClause;
   private String mainTablePrefix;
-  private List extraTables;
-  private int batchSize;
+  private String extraTables;
   private EntityAdapterModel model;
   private String definition;
   private String limitExpression;
   private String skipExpression;
 
   public EntityListProducerNode(String aKey,
-      EntityAdapterModel aModel, String aMainTablePrefix, List someExtraTables,
+      EntityAdapterModel aModel, String aMainTablePrefix, String anExtraTables,
       String aDefinition, String aWhereClause, String anOrderByClause,
       String aLimitExpression, String aSkipExpression, ProducerNode aSubNode) {
     super(aSubNode);
 
     model = aModel;
     mainTablePrefix = aMainTablePrefix;
-    extraTables = someExtraTables;
+    extraTables = anExtraTables;
     definition = aDefinition;
-    key = aKey;
+    keyExpression = aKey;
     whereClause = aWhereClause;
     orderByClause = anOrderByClause;
     limitExpression = aLimitExpression;
     skipExpression = aSkipExpression;
   }
 
-  public EntityListProducerNode(String aKey,
-      EntityAdapterModel aModel, String aMainTablePrefix, List someExtraTables,
-      String aDefinition, String aWhereClause, String anOrderByClause,
-      int aLimit, int aSkip, ProducerNode aSubNode) {
-    this(aKey,  aModel, aMainTablePrefix, someExtraTables,
-          aDefinition, aWhereClause, anOrderByClause,
-          Integer.toString(aLimit), Integer.toString(aSkip), aSubNode);
-  }
-
   public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure, ProducerExc {
     try {
       int limit = ParameterExpander.evaluateIntegerExpressionWithDefault(aValueMap, limitExpression, -1);
@@ -84,36 +74,42 @@ public class EntityListProducerNode extends ProducerNodeDecorator {
 
       if (skipExpression != null && !skipExpression.trim().equals(""))
         skip = ParameterExpander.evaluateIntegerExpression(aValueMap, skipExpression);
+      String key = ParameterExpander.expandExpression(aValueMap, keyExpression);
 
-      ParameterExpander.setValueForKey(
-        aValueMap,
-        key,
-        new CachingRewindableIterator(
-          new EntityIteratorAdapter( mainTablePrefix, extraTables,
-            ParameterExpander.expandExpression( aValueMap, whereClause ),
-            ParameterExpander.expandExpression( aValueMap, orderByClause ),
-            Math.min(50, limit),
-            model,
-            definition,
-            limit,
-            skip )
-        )
-      );
-    }
-    catch (Throwable t) {
-      aLogger.error("cannot retrieve list into key " + key + ": " + t.getMessage());
       try {
         ParameterExpander.setValueForKey(
           aValueMap,
           key,
-          new CachingRewindableIterator(new Vector().iterator())
+          new CachingRewindableIterator(
+            new EntityIteratorAdapter( mainTablePrefix,
+              StringRoutines.splitString(ParameterExpander.expandExpression( aValueMap, extraTables).trim(), ","),
+              ParameterExpander.expandExpression( aValueMap, whereClause ),
+              ParameterExpander.expandExpression( aValueMap, orderByClause ),
+              Math.min(50, limit),
+              model,
+              definition,
+              limit,
+              skip )
+          )
         );
       }
-      catch (Throwable s) {
+      catch (Throwable t) {
+        aLogger.error("cannot retrieve list into keyExpression " + key + ": " + t.getMessage());
+        try {
+          ParameterExpander.setValueForKey(
+            aValueMap,
+            key,
+            new CachingRewindableIterator(Collections.EMPTY_LIST.iterator())
+          );
+        }
+        catch (Throwable s) {
+        }
       }
     }
+    catch (Throwable t) {
+      aLogger.error("cannot process entity list producer node: : " + t.getMessage());
+    }
 
     super.produce(aValueMap, aVerb, aLogger);
-  };
-
+  }
 }
\ No newline at end of file
diff --git a/source/mir/producer/ExecuteProgramProducerNode.java b/source/mir/producer/ExecuteProgramProducerNode.java
new file mode 100755 (executable)
index 0000000..0c57a15
--- /dev/null
@@ -0,0 +1,128 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.producer;\r
+\r
+import java.util.Map;\r
+\r
+import mir.log.LoggerWrapper;\r
+import mir.util.ParameterExpander;\r
+\r
+public class ExecuteProgramProducerNode implements ProducerNode  {\r
+  private String scriptExpression;\r
+  private String maxDurationExpression;\r
+  private String outputVariableExpression;\r
+  private String returnValueVariableExpression;\r
+\r
+  public ExecuteProgramProducerNode(String aScriptExpression, String aMaxDurationExpression, String anOutputVariableExpression,\r
+                                    String aReturnValueVariableExpression) {\r
+    scriptExpression = aScriptExpression;\r
+    maxDurationExpression = aMaxDurationExpression;\r
+    outputVariableExpression = anOutputVariableExpression;\r
+    returnValueVariableExpression = aReturnValueVariableExpression;\r
+  }\r
+\r
+  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {\r
+    String script;\r
+    long maxDuration;\r
+\r
+    try {\r
+      script = ParameterExpander.expandExpression(aValueMap, scriptExpression);\r
+      maxDuration = ParameterExpander.evaluateIntegerExpressionWithDefault(aValueMap, maxDurationExpression, 0);\r
+\r
+      ProcessRunner runner = new ProcessRunner(aLogger, script);\r
+      runner.start();\r
+\r
+      synchronized (runner) {\r
+        runner.wait(maxDuration);\r
+      }\r
+      runner.interrupt();\r
+\r
+      if (runner.getFinished()) {\r
+        aLogger.info(script + " terminated successfully, return value = " + runner.getReturnValue() + ".");\r
+\r
+        if (returnValueVariableExpression != null) {\r
+          ParameterExpander.setValueForKey(aValueMap,\r
+              ParameterExpander.expandExpression(aValueMap, returnValueVariableExpression),\r
+              new Integer(runner.getReturnValue()));\r
+        }\r
+\r
+      }\r
+      else {\r
+        aLogger.info(script + " interrupted prematurely after " + maxDuration + "ms.");\r
+      }\r
+    }\r
+    catch (Throwable e) {\r
+      aLogger.error("Error while executing " + scriptExpression + " : " + e.toString());\r
+    }\r
+  }\r
+\r
+  private static class ProcessRunner extends Thread {\r
+    private String script;\r
+    private boolean finished = false;\r
+    private int returnValue = 0;\r
+    private LoggerWrapper logger;\r
+\r
+    public ProcessRunner(LoggerWrapper aLogger, String aScript) {\r
+      script = aScript;\r
+      logger = aLogger;\r
+    }\r
+\r
+    public boolean getFinished() {\r
+      return finished;\r
+    }\r
+\r
+    public int getReturnValue() {\r
+      return returnValue;\r
+    }\r
+\r
+    public void run() {\r
+      Process process = null;\r
+      try {\r
+        process = Runtime.getRuntime().exec(script);\r
+        returnValue = process.waitFor();\r
+\r
+        finished = true;\r
+\r
+        synchronized (this) {\r
+          this.notify();\r
+        }\r
+      }\r
+      catch (InterruptedException e) {\r
+        if (process!=null) {\r
+          process.destroy();\r
+        }\r
+      }\r
+      catch (Exception e) {\r
+        logger.error(script + " failed to execute: " + e.getMessage());\r
+      }\r
+    }\r
+  }\r
+\r
+}\r
diff --git a/source/mir/producer/ExternalDbProducerNode.java b/source/mir/producer/ExternalDbProducerNode.java
new file mode 100755 (executable)
index 0000000..cfc1e51
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.producer;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.sql.*;
+
+
+import mir.log.LoggerWrapper;
+import mir.util.ExceptionFunctions;
+import mir.util.ParameterExpander;
+
+public class ExternalDbProducerNode extends ProducerNodeDecorator {
+  private String key;
+  private String driver;
+  private String host;
+  private String port;
+  private String database;
+  private String username;
+  private String password;
+  private String query;   
+
+  public ExternalDbProducerNode(String aKey, String aDriver, String aHost, String aPort, String aDatabase, String aUsername, String aPassword,String aQuery,ProducerNode aSubNode) {
+    super(aSubNode);
+    key = aKey;
+    driver = aDriver;
+    host = aHost;
+    port = aPort;
+    database = aDatabase;
+    username = aUsername;
+    password = aPassword;
+    query =aQuery;
+    
+  }
+
+  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
+    try {
+      String expandedKey = ParameterExpander.expandExpression( aValueMap, key );
+      String expandedDriver = ParameterExpander.expandExpression( aValueMap, driver);
+      String expandedHost = ParameterExpander.expandExpression( aValueMap, host);
+      String expandedPort = ParameterExpander.expandExpression( aValueMap, port);
+      String expandedDatabase = ParameterExpander.expandExpression( aValueMap, database);
+      String expandedUsername = ParameterExpander.expandExpression( aValueMap, username);
+      String expandedPassword = ParameterExpander.expandExpression( aValueMap, password);
+      String expandedQuery = ParameterExpander.expandExpression( aValueMap, query);
+
+      if (expandedDriver.equals("postgresql")){
+       Class.forName("org.postgresql.Driver");
+      }
+      if (expandedDriver.equals("mysql")){
+       Class.forName("com.mysql.jdbc.Driver");
+      }
+      else {
+         throw new Exception("Unsupported DB Driver:"+expandedDriver);
+      }
+      
+      Connection db = DriverManager.getConnection("jdbc:"+expandedDriver+"://"+expandedHost
+                                                 +":"+expandedPort+"/"+expandedDatabase
+                                                 , expandedUsername, expandedPassword);
+      
+      Statement st = db.createStatement();
+      ResultSet rs = st.executeQuery(expandedQuery);
+      ResultSetMetaData rsmd = rs.getMetaData();
+      int numberOfColumns= rsmd.getColumnCount();
+      ArrayList fieldNames = new ArrayList(numberOfColumns);     
+      for (int i=0;i<numberOfColumns;i++){
+         fieldNames.add(rsmd.getColumnName(i+1));
+      }
+
+      while(rs.next()  && !isAborted(aValueMap)) {
+       HashMap result=new HashMap();
+       Iterator fields = fieldNames.iterator();
+       while (fields.hasNext()) {
+         String field=(String) fields.next();
+         result.put(field,rs.getString(field));
+       }    
+       ParameterExpander.setValueForKey(aValueMap,expandedKey,result);
+       super.produce(aValueMap, aVerb, aLogger);
+      }
+      rs.close();
+      st.close();
+      db.close();
+    }
+    catch (Throwable t) {
+      Throwable s = ExceptionFunctions.traceCauseException(t);
+      aLogger.error("Error while accessing external database: " + s.getClass().getName()+","+ s.getMessage());
+    }
+  };
+}
index 1ea6d17..50f5b58 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.producer;
@@ -50,7 +50,8 @@ public class FileDateSettingProducerNode extends FileOperationProducerNode {
       Object date = ParameterExpander.findValueForKey( aValueMap, dateExpression );
 
       if (!(date instanceof Date))
-        aLogger.error( "FileDateSettingProducerNode: expression " + dateExpression + " does not evaluate to a Date!") ;
+        aLogger.error( "FileDateSettingProducerNode: expression " +
+            dateExpression + " does not evaluate to a Date!") ;
 
       if (!aFile.setLastModified(((Date) date).getTime())) {
         aLogger.error("Can't set date for " + aFile.getName());
index 0920e64..9841903 100755 (executable)
@@ -41,10 +41,10 @@ public class GeneratingProducerNode implements ProducerNode {
   private String generatorExpression;
   private String destinationExpression;
   private String parametersExpression;
-  private Generator.GeneratorLibrary generatorLibrary;
+  private Generator.Library generatorLibrary;
   private WriterEngine writerEngine;
 
-  public GeneratingProducerNode(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine, String aGenerator, String aDestination, String aParameters) {
+  public GeneratingProducerNode(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine, String aGenerator, String aDestination, String aParameters) {
     generatorExpression=aGenerator;
     destinationExpression=aDestination;
     parametersExpression=aParameters;
@@ -52,7 +52,7 @@ public class GeneratingProducerNode implements ProducerNode {
     writerEngine = aWriterEngine;
   }
 
-  public GeneratingProducerNode(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine, String aGenerator, String aDestination) {
+  public GeneratingProducerNode(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine, String aGenerator, String aDestination) {
     this(aGeneratorLibrary, aWriterEngine, aGenerator, aDestination, "");
   }
 
index d6b9ebe..d3ca018 100755 (executable)
@@ -29,8 +29,8 @@
  */
 package mir.producer;
 
-import java.util.Iterator;
 import java.util.Map;
+import java.util.List;
 
 public interface ProducerFactory {
   public interface ProducerVerb {
@@ -38,10 +38,24 @@ public interface ProducerFactory {
     String getDescription();
   }
 
+  /**
+   * The identifying name of the factory
+   */
   public String getName();
+
+  /**
+   * Returns <code>true</code> if <code>aVerb</code> is a valid verb for this factory
+   */
   public boolean allowVerb(String aVerb);
 
+  /**
+   * Instantiates a producer based on the supplied verb
+   */
   public Producer makeProducer(String aVerb, Map aStartingValues) throws ProducerFailure, ProducerExc;
-  public Iterator verbs(); /* returns ProducerVerbs */
+
+  /**
+   * The set of pre-defined verbs. Returns a list of {@link ProducerVerb}s
+   */
+  public List verbs();
 }
 
index 084e58e..2e0f7c8 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.producer;
@@ -33,6 +33,14 @@ import java.util.Map;
 
 import mir.log.LoggerWrapper;
 
+/**
+ * A <code>ProducerNode</code> is an atom of a noded producer factory.
+ *
+ */
 public interface ProducerNode {
+  /**
+   * Perform the operations of the producer node, based on a verb and a value set.
+   * The supplied logger object should be used for any logging.
+   */
   public void produce(Map aValueSet, String aVerb, LoggerWrapper aLogger) throws ProducerExc, ProducerFailure;
 }
\ No newline at end of file
index d61c96e..9d62022 100755 (executable)
@@ -42,11 +42,17 @@ public class RSSProducerNode implements ProducerNode {
   private String key;
   private String url;
   private String version;
+  private String encoding;
 
-  public RSSProducerNode(String aKey, String anURL, String aVersion) {
+  public RSSProducerNode(String aKey, String aURL, String aVersion) {
+    this (aKey, aURL, aVersion, null);
+  }
+
+  public RSSProducerNode(String aKey, String aURL, String aVersion, String anEncoding) {
     key = aKey;
-    url = anURL;
+    url = aURL;
     version = aVersion;
+    encoding = anEncoding;
   }
 
   public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
@@ -55,16 +61,30 @@ public class RSSProducerNode implements ProducerNode {
       String expandedKey = ParameterExpander.expandExpression( aValueMap, key );
       String expandedUrl = ParameterExpander.expandExpression( aValueMap, url );
       String expandedVersion = ParameterExpander.expandExpression( aValueMap, version );
+      String expandedEncoding = null;
+      if (encoding!=null) {
+        expandedEncoding = ParameterExpander.expandExpression( aValueMap, encoding );
+      }
 
       ParameterExpander.setValueForKey(aValueMap, expandedKey, null);
 
-      if (version.equals("1.0")) {
+      if (expandedVersion.equals("1.0")) {
         RSSReader reader = new RSSReader();
-        rssData = reader.parseUrl(expandedUrl);
+        if (expandedEncoding!=null) {
+          rssData = reader.parseUrl(expandedUrl, expandedEncoding);
+        }
+        else {
+          rssData = reader.parseUrl(expandedUrl);
+        }
       }
-      else if (version.equals("0.91")) {
+      else if (expandedVersion.equals("0.91")) {
         RSS091Reader reader = new RSS091Reader();
-        rssData = reader.parseUrl(expandedUrl);
+        if (expandedEncoding!=null) {
+          rssData = reader.parseUrl(expandedUrl, expandedEncoding);
+        }
+        else {
+          rssData = reader.parseUrl(expandedUrl);
+        }
       }
       ParameterExpander.setValueForKey(aValueMap, expandedKey, rssData);
     }
diff --git a/source/mir/producer/ResourceBundleProducerNode.java b/source/mir/producer/ResourceBundleProducerNode.java
deleted file mode 100755 (executable)
index 26d1118..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.producer;
-
-import java.util.Locale;
-import java.util.Map;
-
-import mir.log.LoggerWrapper;
-import mir.util.ParameterExpander;
-import mir.util.ResourceBundleGeneratorFunction;
-
-import org.apache.struts.util.MessageResources;
-
-public class ResourceBundleProducerNode implements ProducerNode {
-  private String key;
-  private String bundleExpression;
-  private String languageExpression;
-
-  public ResourceBundleProducerNode(String aKey, String aBundleExpression) {
-    this (aKey, aBundleExpression, null);
-  }
-
-  public ResourceBundleProducerNode(String aKey, String aBundleExpression, String aLanguageExpression) {
-    bundleExpression = aBundleExpression;
-    languageExpression = aLanguageExpression;
-    key = aKey;
-  }
-
-  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
-    Object messages;
-
-    try {
-      if (languageExpression!=null) {
-        messages =
-            new ResourceBundleGeneratorFunction(
-                new Locale(ParameterExpander.expandExpression( aValueMap, languageExpression ), "" ),
-                MessageResources.getMessageResources( ParameterExpander.expandExpression( aValueMap, bundleExpression ))
-            );
-      }
-      else {
-        messages =
-          MessageResources.getMessageResources(
-              ParameterExpander.expandExpression( aValueMap, bundleExpression ));
-      }
-      ParameterExpander.setValueForKey( aValueMap, key, messages );
-    }
-    catch (Throwable t) {
-      aLogger.error("Failed to load bundle " + bundleExpression + " for language " + languageExpression +  " into key " + key + ": " + t.getMessage());
-    }
-  };
-
-}
\ No newline at end of file
diff --git a/source/mir/producer/ScriptCallingProducerNode.java b/source/mir/producer/ScriptCallingProducerNode.java
deleted file mode 100755 (executable)
index 75c5191..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*\r
- * Copyright (C) 2001, 2002 The Mir-coders group\r
- *\r
- * This file is part of Mir.\r
- *\r
- * Mir is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * Mir is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with Mir; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * In addition, as a special exception, The Mir-coders gives permission to link\r
- * the code of this program with  any library licensed under the Apache Software License,\r
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
- * (or with modified versions of the above that use the same license as the above),\r
- * and distribute linked combinations including the two.  You must obey the\r
- * GNU General Public License in all respects for all of the code used other than\r
- * the above mentioned libraries.  If you modify this file, you may extend this\r
- * exception to your version of the file, but you are not obligated to do so.\r
- * If you do not wish to do so, delete this exception statement from your version.\r
- */\r
-package mir.producer;\r
-\r
-import java.util.Map;\r
-\r
-import mir.log.LoggerWrapper;\r
-import mir.util.ParameterExpander;\r
-\r
-public class ScriptCallingProducerNode implements ProducerNode  {\r
-  private String scriptExpression;\r
-  private String maxDurationExpression;\r
-\r
-  public ScriptCallingProducerNode(String aScriptExpression, String aMaxDurationExpression) {\r
-    scriptExpression = aScriptExpression;\r
-    maxDurationExpression = aMaxDurationExpression;\r
-  }\r
-\r
-  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {\r
-    String script;\r
-    long maxDuration;\r
-    Process process;\r
-    int returnValue;\r
-\r
-    try {\r
-      script = ParameterExpander.expandExpression(aValueMap, scriptExpression);\r
-      maxDuration = ParameterExpander.evaluateIntegerExpressionWithDefault(aValueMap, maxDurationExpression, 0);\r
-\r
-      ProcessRunner runner = new ProcessRunner(Runtime.getRuntime().exec(script));\r
-      runner.start();\r
-      synchronized (runner) {\r
-        runner.wait(maxDuration);\r
-      }\r
-      runner.interrupt();\r
-\r
-      if (runner.getFinished()) {\r
-        aLogger.info(script + " terminated successfully, return value = " + runner.getReturnValue() + ".");\r
-      }\r
-      else {\r
-        aLogger.info(script + " interrupted prematurely after " + maxDuration + "ms.");\r
-      }\r
-    }\r
-    catch (Throwable e) {\r
-      aLogger.error(scriptExpression + " failed to execute: " + e.getMessage());\r
-    }\r
-  }\r
-\r
-  private static class ProcessRunner extends Thread {\r
-    private Process process;\r
-    private boolean finished = false;\r
-    private int returnValue = 0;\r
-\r
-    public ProcessRunner(Process aProcess) {\r
-      process = aProcess;\r
-    }\r
-\r
-    public boolean getFinished() {\r
-      return finished;\r
-    }\r
-\r
-    public int getReturnValue() {\r
-      return returnValue;\r
-    }\r
-\r
-    public void run() {\r
-      try {\r
-        returnValue = process.waitFor();\r
-        finished = true;\r
-        synchronized (this) {\r
-          this.notify();\r
-        }\r
-      }\r
-      catch (InterruptedException e) {\r
-        process.destroy();\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
index b3024f1..c2f9a01 100755 (executable)
@@ -36,6 +36,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.io.File;
 
 import mir.entity.adapter.EntityAdapterModel;
 import mir.generator.Generator;
@@ -50,6 +51,7 @@ import mir.producer.EntityListProducerNode;
 import mir.producer.EntityModifyingProducerNode;
 import mir.producer.EvaluatedAssignmentProducerNode;
 import mir.producer.ExpandedAssignmentProducerNode;
+import mir.producer.ExternalDbProducerNode;
 import mir.producer.FileDateSettingProducerNode;
 import mir.producer.FileDeletingProducerNode;
 import mir.producer.FreeQueryProducerNode;
@@ -60,24 +62,25 @@ import mir.producer.LoopProducerNode;
 import mir.producer.ProducerNode;
 import mir.producer.RDFAggregatorProducerNode;
 import mir.producer.RSSProducerNode;
-import mir.producer.ResourceBundleProducerNode;
-import mir.producer.ScriptCallingProducerNode;
+import mir.producer.BundleProducerNode;
+import mir.producer.ExecuteProgramProducerNode;
 import mir.util.StringRoutines;
-import mir.util.xml.*;
+import mir.util.xml.XMLParserExc;
 import mir.util.xml.XMLReaderTool;
 
 public class DefaultProducerNodeBuilders {
 
   public static void registerBuilders(ProducerNodeBuilderLibrary aBuilderLibrary,
-       EntityAdapterModel aModel, Generator.GeneratorLibrary aGeneratorLibrary,
-       WriterEngine aWriterEngine, String aSourceBasePath, String aDestinationBasePath) throws ProducerConfigExc {
+       EntityAdapterModel aModel, Generator.Library aGeneratorLibrary,
+       WriterEngine aWriterEngine, File aSourceBasePath, File aDestinationBasePath) throws ProducerConfigExc {
 
     aBuilderLibrary.registerBuilder("Set", EvaluatedAssignmentProducerNodeBuilder.class);
     aBuilderLibrary.registerBuilder("Define", ExpandedAssignmentProducerNodeBuilder.class);
     aBuilderLibrary.registerBuilder("Log", LoggingProducerNodeBuilder.class);
-    aBuilderLibrary.registerBuilder("Execute", ScriptCallingProducerNodeBuilder.class);
-    aBuilderLibrary.registerBuilder("Resource", ResourceBundleProducerNodeBuilder.class);
-    aBuilderLibrary.registerFactory("CopyDir", new DirCopyProducerNodeBuilder.factory( aSourceBasePath, aDestinationBasePath));
+    aBuilderLibrary.registerBuilder("Execute", ExecuteProgramProducerNodeBuilder.class);
+    aBuilderLibrary.registerBuilder("Resource", BundleProducerNodeBuilder.class);
+    aBuilderLibrary.registerBuilder("Bundle", BundleProducerNodeBuilder.class);
+    aBuilderLibrary.registerFactory("CopyDir", new DirCopyProducerNodeBuilder.factory(aSourceBasePath, aDestinationBasePath));
 
     aBuilderLibrary.registerBuilder("DeleteFile", FileDeletingProducerNodeBuilder.class);
     aBuilderLibrary.registerBuilder("SetFileDate", FileDateSettingProducerNodeBuilder.class);
@@ -88,6 +91,7 @@ public class DefaultProducerNodeBuilders {
     aBuilderLibrary.registerBuilder("RDFAggregate", RDFAggregatorProducerNodeBuilder.class);
 
     aBuilderLibrary.registerBuilder("FreeQuery", FreeQueryProducerNodeBuilder.class);
+    aBuilderLibrary.registerBuilder("ExternalDbQuery", ExternalDbProducerNodeBuilder.class);
 
     aBuilderLibrary.registerFactory("Enumerate", new EnumeratingProducerNodeBuilder.factory(aModel));
     aBuilderLibrary.registerFactory("List", new ListProducerNodeBuilder.factory(aModel));
@@ -97,8 +101,7 @@ public class DefaultProducerNodeBuilders {
     aBuilderLibrary.registerFactory("CreateEntity", new CreateEntityProducerNodeBuilder.factory(aModel));
     aBuilderLibrary.registerFactory("DeleteEntity", new DeleteEntityProducerNodeBuilder.factory(aModel));
 
-    aBuilderLibrary.registerFactory("Generate",
-        new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary, aWriterEngine));
+    aBuilderLibrary.registerFactory("Generate", new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary, aWriterEngine));
   }
 
   public static abstract class AbstractProducerNodeBuilder implements ProducerNodeBuilder {
@@ -128,6 +131,7 @@ public class DefaultProducerNodeBuilders {
   // general attribute names, specifc builders reference these, to keep attribute
   //    names consistent
 
+  public final static String   EXTRA_TABLES_ATTRIBUTE = "extratables";
   public final static String   SELECTION_ATTRIBUTE = "selection";
   public final static String   ORDER_ATTRIBUTE = "order";
   public final static String   DEFINITION_ATTRIBUTE = "table";
@@ -154,7 +158,7 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
@@ -177,7 +181,7 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, ASSIGNMENT_REQUIRED_ATTRIBUTES, ASSIGNMENT_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(ASSIGNMENT_KEY_ATTRIBUTE);
       value = (String) anAttributes.get(ASSIGNMENT_VALUE_ATTRIBUTE);
@@ -199,7 +203,7 @@ public class DefaultProducerNodeBuilders {
     private final static String   ENUMERATION_DEFAULT_SUBNODE = "default";
     private final static String   ENUMERATION_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
     private final static String   ENUMERATION_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
-    private final static String   ENUMERATION_EXTRATABLES_ATTRIBUTE = "extratables";
+    private final static String   ENUMERATION_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
     private final static String[] ENUMERATION_LIST_REQUIRED_ATTRIBUTES = { ENUMERATION_LIST_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
     private final static String[] ENUMERATION_LIST_OPTIONAL_ATTRIBUTES = { };
     private final static String[] ENUMERATION_QUERY_REQUIRED_ATTRIBUTES = { ENUMERATION_DEFINITION_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
@@ -209,7 +213,7 @@ public class DefaultProducerNodeBuilders {
     private String key;
     private String definition;
     private String mainTablePrefix;
-    private List   extraTables;
+    private String extraTables;
     private String list;
     private String selection;
     private String order;
@@ -232,17 +236,17 @@ public class DefaultProducerNodeBuilders {
 
 
       if (list!=null)
-        mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_LIST_REQUIRED_ATTRIBUTES, ENUMERATION_LIST_OPTIONAL_ATTRIBUTES);
+        XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_LIST_REQUIRED_ATTRIBUTES, ENUMERATION_LIST_OPTIONAL_ATTRIBUTES);
       if (definition!=null)
-        mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_QUERY_REQUIRED_ATTRIBUTES, ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES);
+        XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_QUERY_REQUIRED_ATTRIBUTES, ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES);
 
 
       key = (String) anAttributes.get(ENUMERATION_KEY_ATTRIBUTE);
-      selection = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
-      order = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
+      selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
+      order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
       limit = (String) anAttributes.get(ENUMERATION_LIMIT_ATTRIBUTE);
       skip = (String) anAttributes.get(ENUMERATION_SKIP_ATTRIBUTE);
-      extraTables = StringRoutines.splitString(mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_EXTRATABLES_ATTRIBUTE,"").trim(), ",");
+      extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_EXTRATABLES_ATTRIBUTE,"");
       if (definition!=null) {
         List parts = StringRoutines.splitString(definition.trim(), " ");
         if (parts.size() > 0)
@@ -390,10 +394,10 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc  {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, LOOP_REQUIRED_ATTRIBUTES, LOOP_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, LOOP_REQUIRED_ATTRIBUTES, LOOP_OPTIONAL_ATTRIBUTES);
 
       condition = (String) anAttributes.get(LOOP_CONDITION_ATTRIBUTE);
-      limit = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, LOOP_LIMIT_ATTRIBUTE, "");
+      limit = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LOOP_LIMIT_ATTRIBUTE, "");
     };
 
     public ProducerNode constructNode() {
@@ -407,7 +411,7 @@ public class DefaultProducerNodeBuilders {
     private final static String   LIST_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
     private final static String   LIST_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
     private final static String   LIST_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
-    private final static String   LIST_EXTRATABLES_ATTRIBUTE = "extratables";
+    private final static String   LIST_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
     private final static String   LIST_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
     private final static String   LIST_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
     private final static String   LIST_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
@@ -418,7 +422,7 @@ public class DefaultProducerNodeBuilders {
     private String key;
     private String definition;
     private String mainTablePrefix;
-    private List   extraTables;
+    private String extraTables;
     private String selection;
     private String order;
     private String limit;
@@ -432,15 +436,15 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, LIST_REQUIRED_ATTRIBUTES, LIST_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, LIST_REQUIRED_ATTRIBUTES, LIST_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(LIST_KEY_ATTRIBUTE);
       definition = (String) anAttributes.get(LIST_DEFINITION_ATTRIBUTE);
-      selection = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_SELECTION_ATTRIBUTE, "");
-      order = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_ORDER_ATTRIBUTE, "");
+      selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_SELECTION_ATTRIBUTE, "");
+      order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_ORDER_ATTRIBUTE, "");
       limit = (String) anAttributes.get(LIST_LIMIT_ATTRIBUTE);
       skip = (String) anAttributes.get(LIST_SKIP_ATTRIBUTE);
-      extraTables = StringRoutines.splitString(mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_EXTRATABLES_ATTRIBUTE,"").trim(), ",");
+      extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LIST_EXTRATABLES_ATTRIBUTE,"");
       List parts = StringRoutines.splitString(definition.trim()," ");
       if (parts.size()>0) definition=(String)parts.get(0);
       if (parts.size()>1) mainTablePrefix=(String)parts.get(1);
@@ -485,10 +489,10 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, DELETEENTITY_REQUIRED_ATTRIBUTES, DELETEENTITY_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, DELETEENTITY_REQUIRED_ATTRIBUTES, DELETEENTITY_OPTIONAL_ATTRIBUTES);
 
       definition = (String) anAttributes.get(DELETEENTITY_DEFINITION_ATTRIBUTE);
-      selection = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, DELETEENTITY_SELECTION_ATTRIBUTE, "");
+      selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, DELETEENTITY_SELECTION_ATTRIBUTE, "");
     };
 
     public ProducerNode constructNode() {
@@ -527,7 +531,7 @@ public class DefaultProducerNodeBuilders {
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
       String typeString;
 
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, LOG_REQUIRED_ATTRIBUTES, LOG_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, LOG_REQUIRED_ATTRIBUTES, LOG_OPTIONAL_ATTRIBUTES);
 
       message = (String) anAttributes.get(LOG_MESSAGE_ATTRIBUTE);
       if (anAttributes.containsKey(LOG_TYPE_ATTRIBUTE)) {
@@ -578,7 +582,7 @@ public class DefaultProducerNodeBuilders {
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
       String typeString;
 
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, FREEQUERY_REQUIRED_ATTRIBUTES, FREEQUERY_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, FREEQUERY_REQUIRED_ATTRIBUTES, FREEQUERY_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(FREEQUERY_KEY_ATTRIBUTE);
       query = (String) anAttributes.get(FREEQUERY_QUERY_ATTRIBUTE);
@@ -606,10 +610,57 @@ public class DefaultProducerNodeBuilders {
       return new FreeQueryProducerNode(key, query, limit, type);
     };
   }
+////////////////////////////////////////////////////////////////////////////////
+
+  public static class ExternalDbProducerNodeBuilder extends AbstractProducerNodeBuilder {
+    private final static String   EXTDB_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
+    private final static String   EXTDB_DRIVER_ATTRIBUTE = "driver";
+    private final static String   EXTDB_HOST_ATTRIBUTE = "host";
+    private final static String   EXTDB_PORT_ATTRIBUTE = "port";
+    private final static String   EXTDB_DATABASE_ATTRIBUTE = "database";
+    private final static String   EXTDB_USERNAME_ATTRIBUTE = "username";
+    private final static String   EXTDB_PASSWORD_ATTRIBUTE = "password";
+    private final static String   EXTDB_QUERY_ATTRIBUTE = "query";
+    private final static String   EXTDB_DEFAULT_SUBNODE = "default";
+    private final static String[] EXTDB_REQUIRED_ATTRIBUTES = { KEY_ATTRIBUTE, EXTDB_DRIVER_ATTRIBUTE, EXTDB_HOST_ATTRIBUTE, EXTDB_PORT_ATTRIBUTE, EXTDB_DATABASE_ATTRIBUTE, EXTDB_USERNAME_ATTRIBUTE, EXTDB_PASSWORD_ATTRIBUTE, EXTDB_QUERY_ATTRIBUTE };
+    private final static String[] EXTDB_OPTIONAL_ATTRIBUTES = { };
+    private final static String[] EXTDB_SUBNODES = {EXTDB_DEFAULT_SUBNODE};
+
+    private String key;
+    private String driver;
+    private String host;
+    private String port;
+    private String database;
+    private String username;
+    private String password;
+    private String query;   
+
+
+    public ExternalDbProducerNodeBuilder() {
+      super(EXTDB_SUBNODES);
+    }
+
+    public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
+      XMLReaderTool.checkAttributes(anAttributes, EXTDB_REQUIRED_ATTRIBUTES, EXTDB_OPTIONAL_ATTRIBUTES);
+
+      key = (String) anAttributes.get(EXTDB_KEY_ATTRIBUTE);
+      driver = (String) anAttributes.get(EXTDB_DRIVER_ATTRIBUTE);
+      host = (String) anAttributes.get(EXTDB_HOST_ATTRIBUTE);
+      port = (String) anAttributes.get(EXTDB_PORT_ATTRIBUTE);
+      database = (String) anAttributes.get(EXTDB_DATABASE_ATTRIBUTE);
+      username = (String) anAttributes.get(EXTDB_USERNAME_ATTRIBUTE);
+      password = (String) anAttributes.get(EXTDB_PASSWORD_ATTRIBUTE);
+      query = (String) anAttributes.get(EXTDB_QUERY_ATTRIBUTE);
+    };
+
+    public ProducerNode constructNode() {
+      return new ExternalDbProducerNode(key, driver, host, port, database, username, password, query,  getSubNode(EXTDB_DEFAULT_SUBNODE));
+    };
+  }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-  public static class ResourceBundleProducerNodeBuilder extends AbstractProducerNodeBuilder {
+  public static class BundleProducerNodeBuilder extends AbstractProducerNodeBuilder {
     private final static String   RESOURCEBUNDLE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
     private final static String   RESOURCEBUNDLE_BUNDLE_ATTRIBUTE = "bundle";
     private final static String   RESOURCEBUNDLE_LANGUAGE_ATTRIBUTE = "language";
@@ -621,12 +672,12 @@ public class DefaultProducerNodeBuilders {
     private String bundle;
     private String language;
 
-    public ResourceBundleProducerNodeBuilder() {
+    public BundleProducerNodeBuilder() {
       super(RESOURCEBUNDLE_SUBNODES);
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, RESOURCEBUNDLE_REQUIRED_ATTRIBUTES, RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, RESOURCEBUNDLE_REQUIRED_ATTRIBUTES, RESOURCEBUNDLE_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(RESOURCEBUNDLE_KEY_ATTRIBUTE);
       bundle = (String) anAttributes.get(RESOURCEBUNDLE_BUNDLE_ATTRIBUTE);
@@ -634,7 +685,7 @@ public class DefaultProducerNodeBuilders {
     };
 
     public ProducerNode constructNode() {
-      return new ResourceBundleProducerNode(key, bundle, language);
+      return new BundleProducerNode(key, bundle, language);
     };
   }
 
@@ -655,7 +706,7 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, FILEDATESETTING_REQUIRED_ATTRIBUTES, FILEDATESETTING_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, FILEDATESETTING_REQUIRED_ATTRIBUTES, FILEDATESETTING_OPTIONAL_ATTRIBUTES);
 
       fileNameKey = (String) anAttributes.get(FILEDATESETTING_FILE_ATTRIBUTE);
       dateKey = (String) anAttributes.get(FILEDATESETTING_DATE_ATTRIBUTE);
@@ -681,7 +732,7 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, FILEDELETING_REQUIRED_ATTRIBUTES, FILEDELETING_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, FILEDELETING_REQUIRED_ATTRIBUTES, FILEDELETING_OPTIONAL_ATTRIBUTES);
 
       fileNameKey = (String) anAttributes.get(FILEDELETING_FILE_ATTRIBUTE);
     };
@@ -693,30 +744,36 @@ public class DefaultProducerNodeBuilders {
 
 ////////////////////////////////////////////////////////////////////////////////
 
-  public static class ScriptCallingProducerNodeBuilder extends AbstractProducerNodeBuilder {
-    private final static String   SCRIPT_COMMAND_ATTRIBUTE = "command";
-    private final static String   SCRIPT_TIME_ATTRIBUTE = "time";
-    private final static String[] SCRIPT_REQUIRED_ATTRIBUTES = { SCRIPT_COMMAND_ATTRIBUTE };
-    private final static String[] SCRIPT_OPTIONAL_ATTRIBUTES = {};
-    private final static String[] SCRIPT_SUBNODES = {};
+  public static class ExecuteProgramProducerNodeBuilder extends AbstractProducerNodeBuilder {
+    private final static String   EXECUTEPROGRAM_COMMAND_ATTRIBUTE = "command";
+    private final static String   EXECUTEPROGRAM_MAXTIME_ATTRIBUTE = "maxduration";
+    private final static String   EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE = "resultvar";
+    private final static String   EXECUTEPROGRAM_RETURNVALUE_ATTRIBUTE = "returnvaluevar";
+    private final static String[] EXECUTEPROGRAM_REQUIRED_ATTRIBUTES = { EXECUTEPROGRAM_COMMAND_ATTRIBUTE };
+    private final static String[] EXECUTEPROGRAM_OPTIONAL_ATTRIBUTES = { EXECUTEPROGRAM_MAXTIME_ATTRIBUTE, EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE };
+    private final static String[] EXECUTEPROGRAM_SUBNODES = {};
 
     private String command;
     private String time;
+    private String resultvar;
+    private String returnValueVar;
 
-    public ScriptCallingProducerNodeBuilder() {
-      super(SCRIPT_SUBNODES);
+    public ExecuteProgramProducerNodeBuilder() {
+      super(EXECUTEPROGRAM_SUBNODES);
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, SCRIPT_REQUIRED_ATTRIBUTES, SCRIPT_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, EXECUTEPROGRAM_REQUIRED_ATTRIBUTES, EXECUTEPROGRAM_OPTIONAL_ATTRIBUTES);
 
-      command = (String) anAttributes.get(SCRIPT_COMMAND_ATTRIBUTE);
-      time = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, SCRIPT_TIME_ATTRIBUTE, "0");
+      command = (String) anAttributes.get(EXECUTEPROGRAM_COMMAND_ATTRIBUTE);
+      time = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_MAXTIME_ATTRIBUTE, null);
+      resultvar = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_RESULTVAR_ATTRIBUTE, null);
+      returnValueVar = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXECUTEPROGRAM_RETURNVALUE_ATTRIBUTE, null);
     };
 
     public ProducerNode constructNode() {
       return new
-          ScriptCallingProducerNode(command, time);
+          ExecuteProgramProducerNode(command, time, resultvar, returnValueVar);
     };
   }
 
@@ -731,10 +788,10 @@ public class DefaultProducerNodeBuilders {
   public static class DirCopyProducerNodeBuilder extends AbstractProducerNodeBuilder {
     private String source;
     private String destination;
-    private String sourceBasePath;
-    private String destinationBasePath;
+    private File sourceBasePath;
+    private File destinationBasePath;
 
-    public DirCopyProducerNodeBuilder(String aSourceBasePath, String aDestinationBasePath) {
+    public DirCopyProducerNodeBuilder(File aSourceBasePath, File aDestinationBasePath) {
       super(DIRCOPY_SUBNODES);
 
       sourceBasePath = aSourceBasePath;
@@ -742,7 +799,7 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, DIRCOPY_REQUIRED_ATTRIBUTES, DIRCOPY_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, DIRCOPY_REQUIRED_ATTRIBUTES, DIRCOPY_OPTIONAL_ATTRIBUTES);
 
       source = (String) anAttributes.get(DIRCOPY_SOURCE_ATTRIBUTE);
       destination = (String) anAttributes.get(DIRCOPY_DESTINATION_ATTRIBUTE);
@@ -753,10 +810,10 @@ public class DefaultProducerNodeBuilders {
     };
 
     public static class factory implements ProducerNodeBuilderFactory {
-      private String sourceBasePath;
-      private String destinationBasePath;
+      private File sourceBasePath;
+      private File destinationBasePath;
 
-      public factory(String aSourceBasePath, String aDestinationBasePath) {
+      public factory(File aSourceBasePath, File aDestinationBasePath) {
         sourceBasePath = aSourceBasePath;
         destinationBasePath = aDestinationBasePath;
       }
@@ -780,10 +837,10 @@ public class DefaultProducerNodeBuilders {
     private String generator;
     private String destination;
     private String parameters;
-    private Generator.GeneratorLibrary generatorLibrary;
+    private Generator.Library generatorLibrary;
     private WriterEngine writerEngine;
 
-    public GeneratingProducerNodeBuilder(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
+    public GeneratingProducerNodeBuilder(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine) {
       super(GENERATION_SUBNODES);
 
       writerEngine = aWriterEngine;
@@ -791,11 +848,11 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, GENERATION_REQUIRED_ATTRIBUTES, GENERATION_OPTIONAL_ATTRIBUTES);
 
       generator = (String) anAttributes.get(GENERATION_GENERATOR_ATTRIBUTE);
       destination = (String) anAttributes.get(GENERATION_DESTINATION_ATTRIBUTE);
-      parameters = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
+      parameters = XMLReaderTool.getStringAttributeWithDefault(anAttributes, GENERATION_PARAMETERS_ATTRIBUTE, "" );
     };
 
     public ProducerNode constructNode() {
@@ -803,10 +860,10 @@ public class DefaultProducerNodeBuilders {
     };
 
     public static class factory implements ProducerNodeBuilderFactory {
-      private Generator.GeneratorLibrary generatorLibrary;
+      private Generator.Library generatorLibrary;
       private WriterEngine writerEngine;
 
-      public factory(Generator.GeneratorLibrary aGeneratorLibrary, WriterEngine aWriterEngine) {
+      public factory(Generator.Library aGeneratorLibrary, WriterEngine aWriterEngine) {
         writerEngine = aWriterEngine;
         generatorLibrary = aGeneratorLibrary;
       }
@@ -832,7 +889,7 @@ public class DefaultProducerNodeBuilders {
     private final static String   BATCHER_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
 
     private final static String   BATCHER_PROCESS_ATTRIBUTE = "process";
-    private final static String   BATCHER_EXTRATABLES_ATTRIBUTE = "extratables";
+    private final static String   BATCHER_EXTRATABLES_ATTRIBUTE = EXTRA_TABLES_ATTRIBUTE;
 
     private final static String   BATCHER_BATCH_SUBNODE = "batches";
     private final static String   BATCHER_BATCHLIST_SUBNODE = "batchlist";
@@ -844,7 +901,7 @@ public class DefaultProducerNodeBuilders {
     private String batchDataKey;
     private String batchInfoKey;
     private String mainTablePrefix;
-    private List extraTables;
+    private String extraTables;
     private String definition;
     private String selection;
     private String order;
@@ -860,22 +917,24 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
-
-      batchDataKey = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
-      batchInfoKey = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
-      definition = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
-      selection = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
-      order = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
-
-      batchSize = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
-      minBatchSize = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
-      skip = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
-      process = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
-      extraTables = StringRoutines.splitString(mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_EXTRATABLES_ATTRIBUTE,"").trim(), ",");
-      List parts = StringRoutines.splitString(definition.trim()," ");
-      if (parts.size()>0) definition=(String)parts.get(0);
-      if (parts.size()>1) mainTablePrefix=(String)parts.get(1);
+      XMLReaderTool.checkAttributes(anAttributes, BATCHER_REQUIRED_ATTRIBUTES, BATCHER_OPTIONAL_ATTRIBUTES);
+
+      batchDataKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DATAKEY_ATTRIBUTE, "data" );
+      batchInfoKey = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_INFOKEY_ATTRIBUTE, "info" );
+      definition = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_DEFINITION_ATTRIBUTE, "" );
+      selection = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SELECTION_ATTRIBUTE, "" );
+      order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_ORDER_ATTRIBUTE, "" );
+
+      batchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_BATCHSIZE_ATTRIBUTE, "20" );
+      minBatchSize = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_MINBATCHSIZE_ATTRIBUTE, "0" );
+      skip = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_SKIP_ATTRIBUTE, "0" );
+      process = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_PROCESS_ATTRIBUTE, "-1" );
+
+      extraTables = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BATCHER_EXTRATABLES_ATTRIBUTE, "");
+
+      List parts = StringRoutines.splitString(definition.trim(), " ");
+      if (parts.size()>0) definition = (String) parts.get(0);
+      if (parts.size()>1) mainTablePrefix = (String) parts.get(1);
     };
 
     public ProducerNode constructNode() {
@@ -928,7 +987,7 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, IF_REQUIRED_ATTRIBUTES, IF_OPTIONAL_ATTRIBUTES);
 
       condition = (String) anAttributes.get( IF_CONDITION_ATTRIBUTE );
     };
@@ -948,30 +1007,33 @@ public class DefaultProducerNodeBuilders {
   public static class RSSProducerNodeBuilder extends AbstractProducerNodeBuilder {
     private final static String   RSS_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
     private final static String   RSS_URL_ATTRIBUTE = URL_ATTRIBUTE;
+    private final static String   RSS_ENCODING_ATTRIBUTE = "encoding";
     private final static String   RSS_VERSION_ATTRIBUTE = "version";
 
     private final static String[] RSS_REQUIRED_ATTRIBUTES = { RSS_KEY_ATTRIBUTE, RSS_URL_ATTRIBUTE };
-    private final static String[] RSS_OPTIONAL_ATTRIBUTES = { RSS_VERSION_ATTRIBUTE };
+    private final static String[] RSS_OPTIONAL_ATTRIBUTES = { RSS_VERSION_ATTRIBUTE, RSS_ENCODING_ATTRIBUTE };
     private final static String[] RSS_SUBNODES = {  };
 
     private String key;
     private String url;
     private String version;
+    private String encoding;
 
     public RSSProducerNodeBuilder() {
       super(RSS_SUBNODES);
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, RSS_REQUIRED_ATTRIBUTES, RSS_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, RSS_REQUIRED_ATTRIBUTES, RSS_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get( RSS_KEY_ATTRIBUTE );
       url = (String) anAttributes.get( RSS_URL_ATTRIBUTE );
-      version = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_VERSION_ATTRIBUTE, "1.0");
+      version = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_VERSION_ATTRIBUTE, "1.0");
+      encoding = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RSS_ENCODING_ATTRIBUTE, null);
     };
 
     public ProducerNode constructNode() {
-      return new RSSProducerNode(key, url, version);
+      return new RSSProducerNode(key, url, version, encoding);
     };
   }
 
@@ -997,12 +1059,12 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, RDF_AGGREGATOR_REQUIRED_ATTRIBUTES, RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, RDF_AGGREGATOR_REQUIRED_ATTRIBUTES, RDF_AGGREGATOR_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get( RDF_AGGREGATOR_KEY_ATTRIBUTE );
       source = (String) anAttributes.get( RDF_AGGREGATOR_SOURCE_ATTRIBUTE );
-      order = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_SOURCE_ATTRIBUTE, "");
-      filter = mir.util.xml.XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_FILTER_ATTRIBUTE, "");
+      order = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_SOURCE_ATTRIBUTE, "");
+      filter = XMLReaderTool.getStringAttributeWithDefault(anAttributes, RDF_AGGREGATOR_FILTER_ATTRIBUTE, "");
     };
 
     public ProducerNode constructNode() {
@@ -1067,7 +1129,7 @@ public class DefaultProducerNodeBuilders {
     };
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
+      XMLReaderTool.checkAttributeSet(anAttributes.keySet(), definition.getRequiredAttributes(), definition.getOptionalAttributes());
 
       Iterator i = anAttributes.entrySet().iterator();
       while (i.hasNext()) {
index b3ffdae..631573f 100755 (executable)
  */
 package  mir.producer.reader;
 
+import java.io.File;
+import java.io.Reader;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.Vector;
-import java.io.File;
 
 import mir.producer.CompositeProducerNode;
 import mir.producer.ProducerFactory;
@@ -55,6 +56,24 @@ public class ProducerConfigReader {
     super();
   };
 
+  public void parse(Reader aReader, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories) throws ProducerConfigFailure {
+    try {
+      builderLibrary = aBuilderLibrary;
+      scriptedNodeBuilderLibrary = new ProducerNodeBuilderLibrary();
+
+      XMLParserEngine.getInstance().parse("", aReader, new RootSectionHandler(aProducerFactories));
+
+    }
+    catch (Throwable e) {
+      Throwable root = ExceptionFunctions.traceCauseException(e);
+
+      if ((root instanceof XMLParserExc) && ((XMLParserExc) root).getHasLocation()) {
+        XMLParserExc f = (XMLParserExc) root;
+        throw new ProducerConfigFailure(f.getMessage()+" on line " + f.getLineNr()+", column " + f.getColumnNr(), e);
+      }
+      throw new ProducerConfigFailure(root);
+    }
+  }
   public void parse(File aFile, ProducerNodeBuilderLibrary aBuilderLibrary, List aProducerFactories) throws ProducerConfigFailure {
     try {
       builderLibrary = aBuilderLibrary;
@@ -237,7 +256,7 @@ public class ProducerConfigReader {
 
     public ProducerVerbsSectionHandler() {
       verbNodes = new HashMap();
-      verbs = new Vector();
+      verbs = new ArrayList();
       defaultVerb = null;
     }
 
index 1a939a1..1964b3c 100755 (executable)
@@ -87,7 +87,7 @@ public class ScriptedProducerFactory implements ProducerFactory {
     return new NodedProducer(rootNode, aVerb, aStartingValues);
   };
 
-  public Iterator verbs() {
-    return verbs.iterator();
+  public List verbs() {
+    return verbs;
   }
 }
\ No newline at end of file
index 18bc0af..a6556b7 100755 (executable)
@@ -36,8 +36,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Vector;
-import mir.util.xml.*;
 
+import mir.util.HTTPClientHelper;
+import mir.util.xml.*;
 import mir.util.xml.XMLParserEngine;
 
 /**
@@ -95,15 +96,49 @@ public class RSS091Reader {
     }
   }
 
-  public RSSData parseUrl(String anUrl) throws RSSExc, RSSFailure {
+  public RSSData parseInputStream(InputStream aStream, String anEncoding) throws RSSExc, RSSFailure {
     try {
-      InputStream inputStream = (InputStream) new URL(anUrl).getContent(new Class[] {InputStream.class});
+      RSSData result = new RSSData();
+      XMLParserEngine.getInstance().parse("html", aStream, anEncoding, new RootSectionHandler(result));
 
+      return result;
+    }
+    catch (Throwable t) {
+      throw new RSSFailure(t);
+    }
+  }
+
+  public RSSData parseUrl(String anUrl) throws RSSExc, RSSFailure {
+    try {
+      HTTPClientHelper httpClientHelper = new HTTPClientHelper();      
+      InputStream inputStream = httpClientHelper.getUrl(anUrl);
       if (inputStream==null)
         throw new RSSExc("RSSChannel.parseUrl: Can't get url content");
 
-      return parseInputStream(inputStream);
+      RSSData theRSSData =  parseInputStream(inputStream);
+      httpClientHelper.releaseHTTPConnection();
+      return theRSSData;
+
+    }
+    catch (Throwable t) {
+      throw new RSSFailure(t);
+    }
+  }
+
+  public RSSData parseUrl(String anUrl, String anEncoding) throws RSSExc, RSSFailure {
+    try {
+      HTTPClientHelper httpClientHelper = new HTTPClientHelper();      
+      InputStream inputStream = httpClientHelper.getUrl(anUrl);
+
+      if (inputStream==null)
+        throw new RSSExc("RSSChannel.parseUrl: Can't get url content");
+      
+      RSSData theRSSData = parseInputStream(inputStream, anEncoding);
+      httpClientHelper.releaseHTTPConnection();
+      return theRSSData;
     }
+
     catch (Throwable t) {
       throw new RSSFailure(t);
     }
@@ -223,7 +258,6 @@ public class RSS091Reader {
 
     public mir.util.xml.SectionHandler startElement(mir.util.xml.XMLName aTag, Map anAttributes) throws XMLParserExc {
       String tag = aTag.getLocalName();
-      System.out.println(tag);
 
       if (mappedItemProperties.containsKey(tag)) {
         currentTag=(String) mappedItemProperties.get(tag);
index a7b48d2..8b44191 100755 (executable)
@@ -30,9 +30,9 @@
 
 package mir.rss;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Vector;
 
 public class RSSAggregator {
   private String orderBy;
@@ -46,7 +46,7 @@ public class RSSAggregator {
     orderBy = anOrderBy;
     orderReversed = anOrderReversed;
     capacity = aCapacity;
-    items = new Vector();
+    items = new ArrayList();
     selectionValue = aSelectionValue;
     selectionField = aSelectionField;
   }
index a5e6181..d858aed 100755 (executable)
@@ -32,7 +32,7 @@ package mir.rss;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
+import java.util.ArrayList;
 
 public class RSSData {
   private List resources;
@@ -40,7 +40,7 @@ public class RSSData {
   private Map identifierToResource;
 
   protected RSSData() {
-    resources = new Vector();
+    resources = new ArrayList();
     rdfClassToResources = new HashMap();
     identifierToResource = new HashMap();
   }
@@ -53,7 +53,7 @@ public class RSSData {
     resources.add(aResource);
     List resourcesForClass = (List) rdfClassToResources.get(aResource.getRdfClass());
     if (resourcesForClass==null) {
-      resourcesForClass = new Vector();
+      resourcesForClass = new ArrayList();
       rdfClassToResources.put(aResource.getRdfClass(), resourcesForClass);
     }
     resourcesForClass.add(aResource);
index 1d7bf40..6d89d49 100755 (executable)
 package mir.rss;
 
 import java.io.InputStream;
-import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
 
 import mir.util.DateTimeFunctions;
+import mir.util.HTTPClientHelper;
 import mir.util.xml.XMLParserEngine;
 import mir.util.xml.XMLParserExc;
 import mir.util.xml.XMLParserFailure;
@@ -77,7 +77,7 @@ public class RSSReader {
   private Map moduleToPrefix;
 
   public RSSReader() {
-    modules = new Vector();
+    modules = new ArrayList();
     namespaceURItoModule = new HashMap();
     moduleToPrefix = new HashMap();
 
@@ -118,7 +118,19 @@ public class RSSReader {
   public RSSData parseInputStream(InputStream aStream) throws RSSExc, RSSFailure {
     try {
       RSSData result = new RSSData();
-      XMLParserEngine.getInstance().parse("xml.namespaceaware", aStream, new RootSectionHandler(result));
+      XMLParserEngine.getInstance().parse("xml", aStream, new RootSectionHandler(result));
+
+      return result;
+    }
+    catch (Throwable t) {
+      throw new RSSFailure(t);
+    }
+  }
+
+  public RSSData parseInputStream(InputStream aStream, String anEncoding) throws RSSExc, RSSFailure {
+    try {
+      RSSData result = new RSSData();
+      XMLParserEngine.getInstance().parse("xml", aStream, anEncoding, new RootSectionHandler(result));
 
       return result;
     }
@@ -129,12 +141,30 @@ public class RSSReader {
 
   public RSSData parseUrl(String anUrl) throws RSSExc, RSSFailure {
     try {
-      InputStream inputStream = (InputStream) new URL(anUrl).getContent(new Class[] {InputStream.class});
+      HTTPClientHelper httpClientHelper = new HTTPClientHelper();      
+      InputStream inputStream = httpClientHelper.getUrl(anUrl);
+      if (inputStream==null)
+        throw new RSSExc("RSSChannel.parseUrl: Can't get url content");
 
+      RSSData theRSSData =  parseInputStream(inputStream);
+      httpClientHelper.releaseHTTPConnection();
+      return theRSSData;
+    }
+    catch (Throwable t) {
+      throw new RSSFailure(t);
+    }
+  }
+
+  public RSSData parseUrl(String anUrl, String anEncoding) throws RSSExc, RSSFailure {
+    try {
+      HTTPClientHelper httpClientHelper = new HTTPClientHelper();      
+      InputStream inputStream = httpClientHelper.getUrl(anUrl);
       if (inputStream==null)
         throw new RSSExc("RSSChannel.parseUrl: Can't get url content");
 
-      return parseInputStream(inputStream);
+      RSSData theRSSData =  parseInputStream(inputStream, anEncoding);
+      httpClientHelper.releaseHTTPConnection();
+      return theRSSData;
     }
     catch (Throwable t) {
       throw new RSSFailure(t);
@@ -235,7 +265,7 @@ public class RSSReader {
         List value = (List) aResource.get(makeQualifiedName(aTag));
 
         if (value==null) {
-          value = new Vector();
+          value = new ArrayList();
           aResource.set(makeQualifiedName(aTag), value);
         }
 
@@ -349,7 +379,7 @@ public class RSSReader {
     private List items;
 
     public RDFCollectionSectionHandler() {
-      items = new Vector();
+      items = new ArrayList();
     }
 
     public mir.util.xml.SectionHandler startElement(String aTag, Map anAttributes) throws XMLParserExc {
@@ -451,7 +481,7 @@ public class RSSReader {
     private List items;
 
     public RDFSequenceSectionHandler() {
-      items = new Vector();
+      items = new ArrayList();
     }
 
     public mir.util.xml.SectionHandler startElement(String aTag, Map anAttributes) throws XMLParserExc {
diff --git a/source/mir/rss/RSSTest.java b/source/mir/rss/RSSTest.java
deleted file mode 100755 (executable)
index 8cece37..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License,
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
- * (or with modified versions of the above that use the same license as the above),
- * and distribute linked combinations including the two.  You must obey the
- * GNU General Public License in all respects for all of the code used other than
- * the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-
-package mir.rss;
-
-import java.util.Iterator;
-
-
-public class RSSTest {
-
-  public static void main(String[] args) {
-
-    RSSReader reader = new RSSReader();
-    try {
-      RSSData res = reader.parseUrl(args[0]);
-      Iterator i = res.getResourcesForRdfClass("rss:item").iterator();
-      while (i.hasNext())
-        System.out.println(i.next());
-    }
-    catch (Throwable t) {
-      System.out.println("Exception: " + t.toString());
-      t.printStackTrace(System.out);
-    }
-  }
-}
index 90aff29..55648f3 100755 (executable)
@@ -46,27 +46,19 @@ import mir.config.MirPropertiesConfiguration;
 import mir.log.LoggerWrapper;
 import mircoders.global.MirGlobal;
 
-import com.codestudio.util.JDBCPool;
-import com.codestudio.util.JDBCPoolMetaData;
-import com.codestudio.util.SQLManager;
-
 /**
  * Title:        Mir
  * Description:  Abstract servlet-class
  * Copyright:    Copyright (c) 2001, 2002
  * Company:      Mir-coders group
  * @author       idfx, the Mir-coders group
- * @version      $Id: AbstractServlet.java,v 1.30.2.6 2003/12/03 18:10:45 rk Exp $
+ * @version      $Id: AbstractServlet.java,v 1.30.2.7 2004/11/21 22:07:13 zapata Exp $
  */
 
 public abstract class AbstractServlet extends HttpServlet {
-  //protected static String lang;
   protected LoggerWrapper logger;
   protected MirPropertiesConfiguration configuration;
 
-  /**
-   * Constructor for AbstractServlet.
-   */
   public AbstractServlet() {
     super();
   }
@@ -76,6 +68,7 @@ public abstract class AbstractServlet extends HttpServlet {
     //
     //this needs to be done here and not per page (via meta tags) as some
     //browsers have problems w/ it per-page -mh
+
     aResponse.setHeader("Pragma", "no-cache");
     aResponse.setDateHeader("Expires", 0);
     aResponse.setHeader("Cache-Control", "no-cache");
@@ -95,13 +88,13 @@ public abstract class AbstractServlet extends HttpServlet {
    * Get the session-bound language
    */
   protected String getLanguage(HttpServletRequest aRequest, HttpSession session) {
-    String lang = (String) session.getAttribute("language");
+    String language = (String) session.getAttribute("language");
 
-    if (lang == null || lang.length()==0) {
-      lang = getAcceptLanguage(aRequest);
+    if (language == null || language.length()==0) {
+      language = getAcceptLanguage(aRequest);
     }
 
-    return lang;
+    return language;
   }
 
   /**
@@ -109,20 +102,20 @@ public abstract class AbstractServlet extends HttpServlet {
    * this supersedes getLanguage for the new i18n
    */
   public Locale getLocale(HttpServletRequest aRequest) {
-    Locale loc = null;
+    Locale locale = null;
     HttpSession session = aRequest.getSession(false);
     if (session != null) {
       // session can be null in case of logout
-      loc = (Locale) session.getAttribute("locale");
+      locale = (Locale) session.getAttribute("locale");
     }
     // if there is nothing in the session get it fron the accept-language
-    if (loc == null) {
-      loc = aRequest.getLocale();
+    if (locale == null) {
+      locale = aRequest.getLocale();
     }
 
-    logger.debug("getting locale: " + loc.getLanguage());
+    logger.debug("getting locale: " + locale.getLanguage());
 
-    return loc;
+    return locale;
   }
 
   /**
@@ -160,47 +153,10 @@ public abstract class AbstractServlet extends HttpServlet {
       throw new ServletException("can't get localizer: " + t.toString());
     }
 
-    String dbUser = configuration.getString("Database.Username");
-    String dbPassword = configuration.getString("Database.Password");
-    String dbHost = configuration.getString("Database.Host");
-    String dbPort = configuration.getString("Database.Port");
-    String dbAdapName = configuration.getString("Database.Adaptor");
-    String dbName = configuration.getString("Database.Name");
-    String dbDriver = configuration.getString("Database.Driver");
-    String dbUrl = "jdbc:postgresql://"+dbHost+":"+dbPort+"/"+dbName;
-    int dbMin = configuration.getInteger("Database.poolMin", 1);
-    int dbMax = configuration.getInteger("Database.poolMax", 10);
-
-    JDBCPoolMetaData meta = new JDBCPoolMetaData();
-    meta.setDbname(dbName);
-    meta.setDriver(dbDriver);
-    meta.setURL(dbUrl);
-    meta.setUserName(dbUser);
-    meta.setPassword(dbPassword);
-    meta.setJNDIName("mir");
-    meta.setMaximumSize(dbMax);
-    meta.setMinimumSize(dbMin);
-    meta.setPoolPreparedStatements(false);
-    meta.setCacheEnabled(false);
-    meta.setCacheSize(15);
-    meta.setDebugging(false);
-
-    SQLManager manager = SQLManager.getInstance();
-
-    JDBCPool pool = null;
-    if (manager != null) {
-      pool = manager.createPool(meta);
-    }
-    
-    if (pool==null) {
-      logger.fatal("Can't get pool!");
-      throw new ServletException("Can't get pool!" );
-    }
-
     Connection connection;
     try {
-      connection = pool.requestConnection();
-           JDBCPool.closeConnection(connection);
+      connection = MirGlobal.getDatabaseEngine().obtainConnection();
+      MirGlobal.getDatabaseEngine().releaseConnection(connection);
     }
     catch (Throwable t) {
       logger.fatal("Can't connect to database: " + t.toString());
@@ -220,7 +176,6 @@ public abstract class AbstractServlet extends HttpServlet {
     }
     catch (NoSuchMethodException e) {
       // TODO set the encoding in a zapata-way
-//      logger.warn("set encoding not yet implemented: " + e.getMessage());
     }
     catch (SecurityException e) {
       logger.error(e.getMessage());
@@ -256,9 +211,6 @@ public abstract class AbstractServlet extends HttpServlet {
 
   /**
    * Selects the language for the response.
-   *
-   * @param session
-   * @param aRequest
    */
   protected void checkLanguage(HttpSession aSession, HttpServletRequest aRequest) {
     String requestLanguage = aRequest.getParameter("language");
index 3eda499..d2d89e8 100755 (executable)
@@ -34,22 +34,23 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
 import mir.config.MirPropertiesConfiguration;
-import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
 import mir.entity.adapter.EntityAdapterEngine;
 import mir.entity.adapter.EntityAdapterModel;
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
+import mir.module.ModuleExc;
 import mir.storage.StorageObject;
 import mir.util.HTTPRequestParser;
 import mir.util.URLBuilder;
 import mircoders.global.MirGlobal;
 import mircoders.servlet.ServletHelper;
+import mircoders.localizer.MirLocalizerExc;
+import multex.Failure;
 
 /**
  *
@@ -64,8 +65,8 @@ import mircoders.servlet.ServletHelper;
 public abstract class ServletModule {
   public String defaultAction;
   protected LoggerWrapper logger;
-  protected MirPropertiesConfiguration configuration;
-  protected Locale fallbackLocale;
+  protected static MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
+  private static Locale fallbackLocale = new Locale(configuration.getString("Mir.Admin.FallbackLanguage", "en"), "");
 
   protected AbstractModule mainModule;
   protected String definition;
@@ -79,15 +80,16 @@ public abstract class ServletModule {
 
   public ServletModule(){
     definition = null;
-    model = null;
-
     try {
-      configuration = MirPropertiesConfiguration.instance();
+      model = MirGlobal.localizer().dataModel().adapterModel();
     }
-    catch (PropertiesConfigExc e) {
-      throw new RuntimeException("Can't get configuration: " + e.getMessage());
+    catch (MirLocalizerExc e) {
+      logger.error("Can't create model: " + e.toString());
+      throw new ServletModuleFailure("Can't retrieve model", e);
     }
 
+
+
     listGenerator = configuration.getString("ServletModule."+getOperationModuleName()+".ListTemplate");
     editGenerator = configuration.getString("ServletModule."+getOperationModuleName()+".EditTemplate");
     deleteConfirmationGenerator = configuration.getString("ServletModule."+getOperationModuleName()+".DeleteConfirmationTemplate");
@@ -95,7 +97,6 @@ public abstract class ServletModule {
         configuration.getInt("ServletModule."+getOperationModuleName()+".ListSize",
         configuration.getInt("ServletModule.Default.ListSize", 20));
 
-    fallbackLocale = new Locale(configuration.getString("Mir.Admin.FallbackLanguage", "en"), "");
   }
 
 
@@ -113,19 +114,21 @@ public abstract class ServletModule {
   }
 
   /**
-   * Get the module name
-   *
-   * @return
+   * Return the module name
    */
   protected String getOperationModuleName() {
     return getClass().getName().substring((new String("mircoders.servlet.ServletModule")).length());
   }
 
+  public static Locale[] getLocales(HttpServletRequest aRequest) {
+    return new Locale[] { getLocale(aRequest), fallbackLocale };
+  }
+
   /**
-   * get the locale either from the session or the accept-language header ot the request
+   * Return the locale either from the session or the accept-language header ot the request
    * this supersedes getLanguage for the new i18n
    */
-  public Locale getLocale(HttpServletRequest aRequest) {
+  public static Locale getLocale(HttpServletRequest aRequest) {
     Locale loc = null;
     HttpSession session = aRequest.getSession(false);
     if (session != null) {
@@ -156,7 +159,7 @@ public abstract class ServletModule {
   public String getDefaultListOrdering() {
 
     if (mainModule!=null && mainModule.getStorageObject()!=null){
-      if (mainModule.getStorageObject().getFields().contains("webdb_create"))
+      if (mainModule.getStorageObject().getFieldNames().contains("webdb_create"))
         return "webdb_create desc";
     }
 
@@ -164,29 +167,7 @@ public abstract class ServletModule {
   }
 
   /**
-   *
-   * @param aResponse
-   * @param aQuery
-   * @throws ServletModuleExc
-   * @throws ServletModuleFailure
-   */
-  public void redirect(HttpServletResponse aResponse, String aQuery) throws ServletModuleExc, ServletModuleFailure {
-    try {
-      aResponse.sendRedirect(aResponse.encodeRedirectURL(MirPropertiesConfiguration.instance().getString("RootUri") + "/servlet/Mir?"+aQuery));
-    }
-    catch (Throwable t) {
-      throw new ServletModuleFailure("ServletModule.redirect: " +t.getMessage(), t);
-    }
-  }
-
-  /**
-   * Generic list method
-   *
-   * @param aRequest
-   * @param aResponse
-   * @throws ServletModuleExc
-   * @throws ServletModuleUserExc
-   * @throws ServletModuleFailure
+   * Generic list servlet method
    */
 
   public void list(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
@@ -209,7 +190,7 @@ public abstract class ServletModule {
     int count;
 
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
 
       List list =
          EntityAdapterEngine.retrieveAdapterList(model, definition, aWhereClause, anOrderByClause, nrEntitiesPerListPage, anOffset);
@@ -275,10 +256,9 @@ public abstract class ServletModule {
   public void editObject(HttpServletRequest aRequest, HttpServletResponse aResponse, Object anObject, boolean anIsNew, String anId) throws ServletModuleExc {
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
     URLBuilder urlBuilder = new URLBuilder();
-    EntityAdapterModel model;
 
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
 
       responseData.put("module", getOperationModuleName());
       responseData.put("entity", anObject);
@@ -303,22 +283,15 @@ public abstract class ServletModule {
     }
   }
 
-
   /**
-   * Generic add method
-   *
-   * @param aRequest
-   * @param aResponse
-   * @throws ServletModuleExc
-   * @throws ServletModuleUserExc
-   * @throws ServletModuleFailure
+   * Generic add servlet method
    */
   public void add(HttpServletRequest aRequest, HttpServletResponse aResponse)
       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure  {
 
     Map object = new HashMap();
 
-    Iterator i = mainModule.getStorageObject().getFields().iterator();
+    Iterator i = mainModule.getStorageObject().getFieldNames().iterator();
 
     while (i.hasNext())
       object.put(i.next(), "");
@@ -332,27 +305,13 @@ public abstract class ServletModule {
   }
 
   /**
-   * Method called when the user edits an object.
-   *
-   * @param aRequest
-   * @param aResponse
-   * @throws ServletModuleExc
-   * @throws ServletModuleUserExc
-   * @throws ServletModuleFailure
+   * Generic edit servlet method
    */
   public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure  {
     edit(aRequest, aResponse, aRequest.getParameter("id"));
   }
 
   /**
-   * Generic edit method
-   *
-   * @param aRequest
-   * @param aResponse
-   * @param anIdentifier
-   * @throws ServletModuleExc
-   * @throws ServletModuleUserExc
-   * @throws ServletModuleFailure
    */
   public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse, String anIdentifier)
       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure  {
@@ -365,13 +324,7 @@ public abstract class ServletModule {
   }
 
   /**
-   * Generic update method
-   *
-   * @param aRequest
-   * @param aResponse
-   * @throws ServletModuleExc
-   * @throws ServletModuleUserExc
-   * @throws ServletModuleFailure
+   * Generic update servlet method
    */
   public void update(HttpServletRequest aRequest, HttpServletResponse aResponse)
       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure  {
@@ -387,7 +340,7 @@ public abstract class ServletModule {
       String returnUrl = requestParser.getParameter("returnurl");
 
       if (returnUrl!=null) {
-        redirect(aResponse, returnUrl);
+        ServletHelper.redirect(aResponse, returnUrl);
       }
       else {
         edit(aRequest, aResponse, id);
@@ -399,13 +352,7 @@ public abstract class ServletModule {
   }
 
   /**
-   * Generic insert method
-   *
-   * @param aRequest
-   * @param aResponse
-   * @throws ServletModuleExc
-   * @throws ServletModuleUserExc
-   * @throws ServletModuleFailure
+   * Generic insert servlet method
    */
   public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse)
       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure  {
@@ -421,7 +368,7 @@ public abstract class ServletModule {
       String returnUrl = requestParser.getParameter("returnurl");
 
       if (returnUrl!=null) {
-        redirect(aResponse, returnUrl);
+        ServletHelper.redirect(aResponse, returnUrl);
       }
       else {
         edit(aRequest, aResponse, id);
@@ -432,33 +379,33 @@ public abstract class ServletModule {
     }
   }
 
+  /**
+   *
+   */
   public String processInstertedObject(Map anObject, HttpServletRequest aRequest, HttpServletResponse aResponse) {
     try {
       return mainModule.add(anObject);
     }
-    catch (Throwable t) {
+    catch (ModuleExc t) {
       throw new ServletModuleFailure(t);
     }
   };
 
   /**
-   *
-   * @param aRequest
-   * @param aResponse
+   * Generic delete confirmation servlet method
    */
   public void confirmdelete(HttpServletRequest aRequest, HttpServletResponse aResponse) {
     try {
       String idParam = aRequest.getParameter("id");
       String confirmParam = aRequest.getParameter("confirm");
-      String cancelParam = aRequest.getParameter("cancel");
 
       if (confirmParam != null && !confirmParam.equals("")) {
         mainModule.deleteById(idParam);
         logAdminUsage(aRequest, idParam, "object deleted");
-        redirect(aResponse, aRequest.getParameter("okurl"));
+        ServletHelper.redirect(aResponse, aRequest.getParameter("okurl"));
       }
       else
-        redirect(aResponse, aRequest.getParameter("cancelurl"));
+        ServletHelper.redirect(aResponse, aRequest.getParameter("cancelurl"));
     }
     catch (Throwable t) {
       throw new ServletModuleFailure(t);
@@ -466,12 +413,7 @@ public abstract class ServletModule {
   }
 
   /**
-   *
-   * @param aRequest
-   * @param aResponse
-   * @throws ServletModuleExc
-   * @throws ServletModuleUserExc
-   * @throws ServletModuleFailure
+   * Generic delete servlet method
    */
   public void delete(HttpServletRequest aRequest, HttpServletResponse aResponse)
       throws ServletModuleExc, ServletModuleUserExc, ServletModuleFailure  {
@@ -481,7 +423,7 @@ public abstract class ServletModule {
       if (idParam == null)
         throw new ServletModuleExc("Invalid call to delete: no id supplied");
 
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
 
       responseData.put("module", getOperationModuleName());
       responseData.put("id", idParam);
@@ -496,11 +438,6 @@ public abstract class ServletModule {
   }
 
   /**
-   *  Wenn die abgeleitete Klasse diese Methode ueberschreibt und einen String mit einem
-   *  Methodennamen zurueckliefert, dann wird diese Methode bei fehlender Angabe des
-   *  doParameters ausgefuehrt.
-   *
-   * @return Name der Default-Action
    */
   public String defaultAction() {
     return defaultAction;
@@ -515,30 +452,23 @@ public abstract class ServletModule {
   public Map getIntersectingValues(HttpServletRequest aRequest, StorageObject theStorage)
       throws ServletModuleExc, ServletModuleFailure {
 
-    try {
-      HTTPRequestParser parser;
-      List theFieldList;
+    HTTPRequestParser parser;
+    List theFieldList;
 
-      parser = new HTTPRequestParser(aRequest);
+    parser = new HTTPRequestParser(aRequest);
 
-      theFieldList = theStorage.getFields();
+    theFieldList = theStorage.getFieldNames();
 
-      Map withValues = new HashMap();
-      String aField, aValue;
+    Map withValues = new HashMap();
+    String aField, aValue;
 
-      for (int i = 0; i < theFieldList.size(); i++) {
-        aField = (String) theFieldList.get(i);
-
-        aValue = parser.getParameter(aField);
-        if (aValue != null)
-          withValues.put(aField, aValue);
-      }
-      return withValues;
-    }
-    catch (Throwable e) {
-      e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+    for (int i = 0; i < theFieldList.size(); i++) {
+      aField = (String) theFieldList.get(i);
 
-      throw new ServletModuleFailure( "ServletModule.getIntersectingValues: " + e.getMessage(), e);
+      aValue = parser.getParameter(aField);
+      if (aValue != null)
+        withValues.put(aField, aValue);
     }
+    return withValues;
   }
 }
\ No newline at end of file
index 4b607ca..968c004 100755 (executable)
  */
 package mir.session;
 
-import java.io.InputStream;
-
 import org.apache.commons.fileupload.FileItem;
 
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+
 public class CommonsUploadedFileAdapter implements UploadedFile {
   private FileItem fileItem;
 
@@ -40,14 +42,25 @@ public class CommonsUploadedFileAdapter implements UploadedFile {
     fileItem = aFileItem;
   }
 
-  public InputStream getInputStream() throws SessionExc, SessionFailure{
+  public void writeToFile(File aFile) throws SessionExc, SessionFailure {
+    try {
+      aFile.getParentFile().mkdirs();
+      fileItem.write(aFile);
+    }
+    catch (Exception e) {
+      e.printStackTrace();
+      throw new SessionFailure(e);
+    }
+  }
+
+  public InputStream getInputStream() throws SessionExc, SessionFailure {
     try {
       return fileItem.getInputStream();
     }
-    catch (Throwable t) {
-      throw new SessionFailure(t);
+    catch (IOException e) {
+      throw new SessionFailure(e);
     }
-  };
+  }
 
   public String getFileName() {
     return fileItem.getName();
index 5dcc510..08c8221 100755 (executable)
  */
 package mir.session;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Vector;
-
+import java.util.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 
 import mir.util.HTTPParsedRequest;
-
 import org.apache.commons.fileupload.FileItem;
 
 public class HTTPAdapters {
   public static class HTTPRequestAdapter implements Request {
     private HttpServletRequest request;
+    private String cachedHostName = null;
 
     public HTTPRequestAdapter(HttpServletRequest aRequest) {
       request = aRequest;
@@ -52,6 +51,22 @@ public class HTTPAdapters {
       if (aHeaderName.equals("ip"))
         return request.getRemoteAddr();
 
+      if (aHeaderName.equals("hostname")) {
+        if (aHeaderName.equals("hostname")) {
+          if (cachedHostName==null) {
+            try {
+              cachedHostName = InetAddress.getByName(request.getRemoteAddr()).getHostName();
+            }
+            catch (UnknownHostException e) {
+              cachedHostName = request.getRemoteAddr();
+            }
+          }
+
+          return cachedHostName;
+        }
+
+      }
+
       return request.getHeader(aHeaderName);
     };
 
@@ -59,8 +74,22 @@ public class HTTPAdapters {
       return request.getParameter(aName);
     };
 
+    public List getPrefixedParameterNames(String aPrefix) {
+      List result = new ArrayList();
+
+      Enumeration enumeration = request.getParameterNames();
+      while (enumeration.hasMoreElements()) {
+        String name = (String) enumeration.nextElement();
+        if (name.startsWith(aPrefix)) {
+          result.add(name);
+        }
+      }
+
+      return result;
+    };
+
     public List getUploadedFiles() {
-      return new Vector();
+      return Collections.EMPTY_LIST;
     };
 
     public List getParameters(String aName) {
@@ -74,6 +103,7 @@ public class HTTPAdapters {
 
   public static class HTTPParsedRequestAdapter implements Request {
     private HTTPParsedRequest request;
+    private String cachedHostName = null;
 
     public HTTPParsedRequestAdapter(HTTPParsedRequest aRequest) {
       request = aRequest;
@@ -83,8 +113,21 @@ public class HTTPAdapters {
       if (aHeaderName.equals("ip"))
         return request.getRequest().getRemoteAddr();
 
+      if (aHeaderName.equals("hostname")) {
+        if (cachedHostName==null) {
+          try {
+            cachedHostName = InetAddress.getByName(request.getRequest().getRemoteAddr()).getHostName();
+          }
+          catch (UnknownHostException e) {
+            cachedHostName = request.getRequest().getRemoteAddr();
+          }
+        }
+
+        return cachedHostName;
+      }
+
       return request.getHeader(aHeaderName);
-    };
+    }
 
     public String getParameter(String aName) {
       return request.getParameter(aName);
@@ -94,8 +137,23 @@ public class HTTPAdapters {
       return request.getParameterList(aName);
     };
 
+    public List getPrefixedParameterNames(String aPrefix) {
+      List result = new ArrayList();
+
+      Iterator i = request.getParameterNames().iterator();
+
+      while (i.hasNext()) {
+        String name = (String) i.next();
+        if (name.startsWith(aPrefix)) {
+          result.add(name);
+        }
+      }
+
+      return result;
+    };
+
     public List getUploadedFiles() {
-      List result = new Vector();
+      List result = new ArrayList();
       List files = request.getFiles();
 
       for (int i=0; i<files.size(); i++) {
index 3133000..ce0bf07 100755 (executable)
@@ -35,5 +35,6 @@ public interface Request {
   public String getParameter(String aName);
   public List getUploadedFiles();
   public List getParameters(String aName);
+  public List getPrefixedParameterNames(String aPrefix);
   public String getHeader(String aHeaderName);
 }
\ No newline at end of file
index 731fcee..89e54bd 100755 (executable)
  */
 package mir.session;
 
+import java.io.File;
 import java.io.InputStream;
 
 public interface UploadedFile {
-  InputStream getInputStream() throws SessionExc, SessionFailure;
-  String getFileName();
-  String getFieldName();
-  String getContentType();
+  /**
+   * Writes the uploaded content to a file
+   */
+  public void writeToFile(File aFile) throws SessionExc, SessionFailure;
+
+  /**
+   * Creates an <code>InputStream</code> to access the uploaded content  
+   */
+  public InputStream getInputStream() throws SessionExc, SessionFailure;
+
+  /**
+   * Return the filename supplied by the uploader if available.
+   * <code>null</code> if no filename is available.
+   */
+  public String getFileName();
+
+  /**
+   * Return the field name associated with the uploaded file
+   */
+  public String getFieldName();
+
+  /**
+   * Return the content type (if it's present) of the uploaded file.
+   * <code>null</code> if no content type is available. 
+   */
+  public String getContentType();
 }
\ No newline at end of file
index a236a48..9876791 100755 (executable)
  */
 package mir.storage;
 
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.Timestamp;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.Vector;
-
 import mir.config.MirPropertiesConfiguration;
-import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
 import mir.entity.Entity;
 import mir.entity.EntityList;
 import mir.entity.StorableObjectEntity;
 import mir.log.LoggerWrapper;
 import mir.misc.StringUtil;
-import mir.storage.store.ObjectStore;
-import mir.storage.store.StorableObject;
-import mir.storage.store.StoreContainerType;
-import mir.storage.store.StoreIdentifier;
-import mir.storage.store.StoreUtil;
+import mir.storage.store.*;
 import mir.util.JDBCStringRoutines;
+import mircoders.global.MirGlobal;
 
-import com.codestudio.util.SQLManager;
-
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.sql.*;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
 
 /**
- * Diese Klasse implementiert die Zugriffsschicht auf die Datenbank.
- * Alle Projektspezifischen Datenbankklassen erben von dieser Klasse.
- * In den Unterklassen wird im Minimalfall nur die Tabelle angegeben.
- * Im Konfigurationsfile findet sich eine Verweis auf den verwendeten
- * Treiber, Host, User und Passwort, ueber den der Zugriff auf die
- * Datenbank erfolgt.
+ * Implements database access.
  *
- * @version $Id: Database.java,v 1.44.2.22 2004/02/08 21:05:01 zapata Exp $
+ * @version $Id: Database.java,v 1.44.2.23 2004/11/21 22:07:13 zapata Exp $
  * @author rk
  *
  */
@@ -85,16 +61,15 @@ public class Database implements StorageObject {
   private static final int _millisPerHour = 60 * 60 * 1000;
 
   protected LoggerWrapper logger;
+
   protected MirPropertiesConfiguration configuration;
   protected String mainTable;
   protected String primaryKeySequence = null;
   protected String primaryKeyField = "id";
 
-  protected boolean evaluatedMetaData = false;
-  protected ArrayList metadataFields;
-  protected ArrayList metadataLabels;
-  protected ArrayList metadataNotNullFields;
-  protected int[] metadataTypes;
+  protected List fieldNames;
+  protected int[] fieldTypes;
+
   protected Class theEntityClass;
   protected boolean hasTimestamp = true;
   private int defaultLimit;
@@ -112,12 +87,7 @@ public class Database implements StorageObject {
    * erzeugt.
    */
   public Database() throws StorageObjectFailure {
-    try {
-      configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (PropertiesConfigExc e) {
-      throw new StorageObjectFailure(e);
-    }
+    configuration = MirPropertiesConfiguration.instance();
     logger = new LoggerWrapper("Database");
     timezone = TimeZone.getTimeZone(configuration.getString("Mir.DefaultTimezone"));
     internalDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -192,39 +162,14 @@ public class Database implements StorageObject {
   }
 
   /**
-   * Liefert Feldtypen der Felder der Tabelle zurueck (s.a. java.sql.Types)
-   * @return int-Array mit den Typen der Felder
-   * @exception StorageObjectFailure
-   */
-  public int[] getTypes() throws StorageObjectFailure {
-    if (metadataTypes == null) {
-      get_meta_data();
-    }
-
-    return metadataTypes;
-  }
-
-  /**
-   * Liefert eine Liste der Labels der Tabellenfelder
+   * {@inheritDoc}
    */
-  public List getLabels() throws StorageObjectFailure {
-    if (metadataLabels == null) {
-      get_meta_data();
+  public List getFieldNames() throws StorageObjectFailure {
+    if (fieldNames == null) {
+      retrieveMetaData();
     }
 
-    return metadataLabels;
-  }
-
-  /**
-   * Liefert eine Liste der Felder der Tabelle
-   * @return ArrayList mit Feldern
-   */
-  public List getFields() throws StorageObjectFailure {
-    if (metadataFields == null) {
-      get_meta_data();
-    }
-
-    return metadataFields;
+    return fieldNames;
   }
 
   /**
@@ -388,7 +333,7 @@ public class Database implements StorageObject {
     }
 
     Statement stmt = null;
-    Connection con = getPooledCon();
+    Connection con = obtainConnection();
     Entity returnEntity = null;
 
     try {
@@ -401,10 +346,6 @@ public class Database implements StorageObject {
       rs = executeSql(stmt, selectSql);
 
       if (rs != null) {
-        if (evaluatedMetaData == false) {
-          evalMetaData(rs.getMetaData());
-        }
-
         if (rs.next()) {
           returnEntity = makeEntityFromResultSet(rs);
         }
@@ -448,25 +389,12 @@ public class Database implements StorageObject {
        return selectByWhereClause( mainTablePrefix, extraTables, aWhereClause, "", 0, defaultLimit);
   }
 
-  /**
-   *   select-Operator um Datensaetze zu bekommen, die key = value erfuellen.
-   *   @param aField  Datenbankfeld der Bedingung.
-   *   @param aValue  Wert die der key anehmen muss.
-   *   @return EntityList mit den gematchten Entities
-   */
   public EntityList selectByFieldValue(String aField, String aValue) throws StorageObjectFailure {
     return selectByFieldValue(aField, aValue, 0);
   }
 
-  /**
-   *   select-Operator um Datensaetze zu bekommen, die key = value erfuellen.
-   *   @param aField  Datenbankfeld der Bedingung.
-   *   @param aValue  Wert die der key anehmen muss.
-   *   @param offset  Gibt an ab welchem Datensatz angezeigt werden soll.
-   *   @return EntityList mit den gematchten Entities
-   */
   public EntityList selectByFieldValue(String aField, String aValue, int offset) throws StorageObjectFailure {
-    return selectByWhereClause(aField + "=" + aValue, offset);
+    return selectByWhereClause(aField + "='" + JDBCStringRoutines.escapeStringLiteral(aValue)+"'", offset);
   }
 
   /**
@@ -545,39 +473,41 @@ public class Database implements StorageObject {
    * select-Operator returns EntityList with matching rows in Database.
    * @param aWhereClause where-Clause
    * @param anOrderByClause orderBy-Clause
-   * @param offset ab welchem Datensatz
-   * @param limit wieviele Datens?tze
+   * @param anOffset ab welchem Datensatz
+   * @param aLimit wieviele Datens?tze
    * @return EntityList mit den gematchten Entities
    * @exception StorageObjectFailure
    */
-  public EntityList selectByWhereClause(String mainTablePrefix, List extraTables,
+  public EntityList selectByWhereClause(
+      String aMainTablePrefix, List anExtraTables,
       String aWhereClause, String anOrderByClause,
-                       int offset, int limit) throws StorageObjectFailure {
+                       int anOffset, int aLimit) throws StorageObjectFailure {
 
-    // TODO get rid of emtpy Strings in extraTables
-    // make extraTables null, if single empty String in it
+    // TODO get rid of emtpy Strings in anExtraTables
+    // make anExtraTables null, if single empty String in it
     // cause StringUtil.splitString puts in emptyString
-    if (extraTables != null && ((String)extraTables.get(0)).trim().equals(""))
-      {
-        logger.debug("+++ made extraTables to null!");
-        extraTables=null;
-      }
 
-      String useTable = mainTable;
-          String selectStar = "*";
-          if (mainTablePrefix!=null && mainTablePrefix.trim().length()>0) {
-            useTable+=" "+mainTablePrefix;
-            selectStar=mainTablePrefix.trim() + ".*";
-          }
+    if (anExtraTables!=null && ((String) anExtraTables.get(0)).trim().equals("")){
+      logger.debug("+++ made anExtraTables to null!");
+      anExtraTables=null;
+    }
+
+    String useTable = mainTable;
+    String selection = "*";
+
+    if (aMainTablePrefix != null && aMainTablePrefix.trim().length() > 0) {
+      useTable += " " + aMainTablePrefix;
+      selection = aMainTablePrefix.trim() + ".*";
+    }
 
     // check o_store for entitylist
     // only if no relational select
-    if (extraTables==null) {
+    if (anExtraTables==null) {
       if (StoreUtil.extendsStorableEntity(theEntityClass)) {
          StoreIdentifier searchSid = new StoreIdentifier(theEntityClass,
                StoreContainerType.STOC_TYPE_ENTITYLIST,
                StoreUtil.getEntityListUniqueIdentifierFor(mainTable,
-                aWhereClause, anOrderByClause, offset, limit));
+                aWhereClause, anOrderByClause, anOffset, aLimit));
          EntityList hit = (EntityList) o_store.use(searchSid);
 
          if (hit != null) {
@@ -588,9 +518,10 @@ public class Database implements StorageObject {
 
     // local
     EntityList theReturnList = null;
-    Connection con = null;
-    Statement stmt = null;
-    ResultSet rs;
+    Connection connection = null;
+    Statement statement = null;
+    ResultSet resultSet;
+
     int offsetCount = 0;
     int count = 0;
 
@@ -603,14 +534,14 @@ public class Database implements StorageObject {
     StringBuffer countSql =
       new StringBuffer("select count(*) from ").append(useTable);
     StringBuffer selectSql =
-      new StringBuffer("select "+selectStar+" from ").append(useTable);
+      new StringBuffer("select "+selection+" from ").append(useTable);
 
     // append extratables, if necessary
-    if (extraTables!=null) {
-      for (int i=0;i < extraTables.size();i++) {
-        if (!extraTables.get(i).equals("")) {
-          countSql.append( ", " + extraTables.get(i));
-          selectSql.append( ", " + extraTables.get(i));
+    if (anExtraTables!=null) {
+      for (int i=0;i < anExtraTables.size();i++) {
+        if (!anExtraTables.get(i).equals("")) {
+          countSql.append( ", " + anExtraTables.get(i));
+          selectSql.append( ", " + anExtraTables.get(i));
         }
       }
     }
@@ -624,31 +555,27 @@ public class Database implements StorageObject {
       selectSql.append(" order by ").append(anOrderByClause);
     }
 
-    if ((limit > -1) && (offset > -1)) {
-      selectSql.append(" LIMIT ").append(limit).append(" OFFSET ").append(offset);
+    if ((aLimit > -1) && (anOffset > -1)) {
+      selectSql.append(" LIMIT ").append(aLimit).append(" OFFSET ").append(anOffset);
     }
 
     // execute sql
     try {
-      con = getPooledCon();
-      stmt = con.createStatement();
+      connection = obtainConnection();
+      statement = connection.createStatement();
 
       // selecting...
-      rs = executeSql(stmt, selectSql.toString());
-
-      if (rs != null) {
-        if (!evaluatedMetaData) {
-          evalMetaData(rs.getMetaData());
-        }
+      resultSet = executeSql(statement, selectSql.toString());
 
+      if (resultSet != null) {
         theReturnList = new EntityList();
         Entity theResultEntity;
-        while (rs.next()) {
-          theResultEntity = makeEntityFromResultSet(rs);
+        while (resultSet.next()) {
+          theResultEntity = makeEntityFromResultSet(resultSet);
           theReturnList.add(theResultEntity);
           offsetCount++;
         }
-        rs.close();
+        resultSet.close();
       }
 
       // making entitylist infos
@@ -658,16 +585,16 @@ public class Database implements StorageObject {
         // now we decide if we have to know an overall count...
         count = offsetCount;
 
-        if ((limit > -1) && (offset > -1)) {
-          if (offsetCount == limit) {
-            rs = executeSql(stmt, countSql.toString());
+        if ((aLimit > -1) && (anOffset > -1)) {
+          if (offsetCount == aLimit) {
+            resultSet = executeSql(statement, countSql.toString());
 
-            if (rs != null) {
-              if (rs.next()) {
-                count = rs.getInt(1);
+            if (resultSet != null) {
+              if (resultSet.next()) {
+                count = resultSet.getInt(1);
               }
 
-              rs.close();
+              resultSet.close();
             }
             else {
               logger.error("Could not count: " + countSql);
@@ -676,21 +603,21 @@ public class Database implements StorageObject {
         }
 
         theReturnList.setCount(count);
-        theReturnList.setOffset(offset);
+        theReturnList.setOffset(anOffset);
         theReturnList.setWhere(aWhereClause);
         theReturnList.setOrder(anOrderByClause);
         theReturnList.setStorage(this);
-        theReturnList.setLimit(limit);
+        theReturnList.setLimit(aLimit);
 
-        if (offset >= limit) {
-          theReturnList.setPrevBatch(offset - limit);
+        if (anOffset >= aLimit) {
+          theReturnList.setPrevBatch(anOffset - aLimit);
         }
 
-        if ((offset + offsetCount) < count) {
-          theReturnList.setNextBatch(offset + limit);
+        if ((anOffset + offsetCount) < count) {
+          theReturnList.setNextBatch(anOffset + aLimit);
         }
 
-        if (extraTables==null && StoreUtil.extendsStorableEntity(theEntityClass)) {
+        if (anExtraTables==null && StoreUtil.extendsStorableEntity(theEntityClass)) {
           StoreIdentifier sid = theReturnList.getStoreIdentifier();
           logger.debug("CACHE (add): " + sid.toString());
           o_store.add(sid);
@@ -702,8 +629,8 @@ public class Database implements StorageObject {
     }
     finally {
       try {
-        if (con != null) {
-          freeConnection(con, stmt);
+        if (connection != null) {
+          freeConnection(connection, statement);
         }
       } catch (Throwable t) {
       }
@@ -722,7 +649,7 @@ public class Database implements StorageObject {
     throws StorageObjectFailure {
     Map theResultHash = new HashMap();
     String theResult = null;
-    int theType;
+    int type;
     Entity returnEntity = null;
 
     try {
@@ -733,14 +660,11 @@ public class Database implements StorageObject {
          if (hit != null) return hit;
       }
 
-
-      int size = metadataFields.size();
-
-      for (int i = 0; i < size; i++) {
+      for (int i = 0; i < getFieldNames().size(); i++) {
         // alle durchlaufen bis nix mehr da
-        theType = metadataTypes[i];
+        type = fieldTypes[i];
 
-        if (theType == java.sql.Types.LONGVARBINARY) {
+        if (type == java.sql.Types.LONGVARBINARY) {
           InputStreamReader is =
             (InputStreamReader) rs.getCharacterStream(i + 1);
 
@@ -755,15 +679,17 @@ public class Database implements StorageObject {
 
             is.close();
             theResult = theResultString.toString();
-          } else {
+          }
+          else {
             theResult = null;
           }
-        } else {
-          theResult = getValueAsString(rs, (i + 1), theType);
+        }
+        else {
+          theResult = getValueAsString(rs, (i + 1), type);
         }
 
         if (theResult != null) {
-          theResultHash.put(metadataFields.get(i), theResult);
+          theResultHash.put(getFieldNames().get(i), theResult);
         }
       }
 
@@ -805,16 +731,7 @@ public class Database implements StorageObject {
    * @return der Wert des Primary-keys der eingef?gten Entity
    */
   public String insert(Entity theEntity) throws StorageObjectFailure {
-    //cache
-    invalidatePopupCache();
-
-    // invalidating all EntityLists corresponding with theEntityClass
-    if (StoreUtil.extendsStorableEntity(theEntityClass)) {
-      StoreContainerType stoc_type =
-        StoreContainerType.valueOf(theEntityClass,
-          StoreContainerType.STOC_TYPE_ENTITYLIST);
-      o_store.invalidate(stoc_type);
-    }
+    invalidateStore();
 
     String returnId = null;
     Connection con = null;
@@ -828,8 +745,8 @@ public class Database implements StorageObject {
       boolean firstField = true;
 
       // make sql-string
-      for (int i = 0; i < getFields().size(); i++) {
-        aField = (String) getFields().get(i);
+      for (int i = 0; i < getFieldNames().size(); i++) {
+        aField = (String) getFieldNames().get(i);
 
         if (!aField.equals(primaryKeyField)) {
           aValue = null;
@@ -872,7 +789,7 @@ public class Database implements StorageObject {
       String sql = sqlBuf.toString();
 
       logger.info("INSERT: " + sql);
-      con = getPooledCon();
+      con = obtainConnection();
       con.setAutoCommit(false);
       pstmt = con.prepareStatement(sql);
 
@@ -920,27 +837,21 @@ public class Database implements StorageObject {
      *  that chooses to either insert or update depending if we
      *  have a primary key in the entity. i don't know if we
      *  still need the streamed input fields. // rk  */
+
     /** todo extension: check if Entity did change, otherwise we don't need
      *  the roundtrip to the database */
     /** invalidating corresponding entitylists in o_store*/
-    if (StoreUtil.extendsStorableEntity(theEntityClass)) {
-      StoreContainerType stoc_type =
-        StoreContainerType.valueOf(theEntityClass,
-          StoreContainerType.STOC_TYPE_ENTITYLIST);
-      o_store.invalidate(stoc_type);
-    }
+
+    invalidateStore();
 
     String id = theEntity.getId();
     String aField;
     StringBuffer fv = new StringBuffer();
     boolean firstField = true;
 
-    //cache
-    invalidatePopupCache();
-
     // build sql statement
-    for (int i = 0; i < getFields().size(); i++) {
-      aField = (String) metadataFields.get(i);
+    for (int i = 0; i < getFieldNames().size(); i++) {
+      aField = (String) getFieldNames().get(i);
 
       // only normal cases
       // todo if entity.hasFieldValue returns false, then the value should be stored as null
@@ -966,13 +877,13 @@ public class Database implements StorageObject {
       new StringBuffer("update ").append(mainTable).append(" set ").append(fv);
 
     // exceptions
-    if (metadataFields.contains("webdb_lastchange")) {
+    if (getFieldNames().contains("webdb_lastchange")) {
       sql.append(",webdb_lastchange=NOW()");
     }
 
     // special case: the webdb_create requires the field in yyyy-mm-dd HH:mm
     // format so anything extra will be ignored. -mh
-    if (metadataFields.contains("webdb_create") &&
+    if (getFieldNames().contains("webdb_create") &&
         theEntity.hasFieldValue("webdb_create")) {
       // minimum of 10 (yyyy-mm-dd)...
       if (theEntity.getFieldValue("webdb_create").length() >= 10) {
@@ -999,7 +910,7 @@ public class Database implements StorageObject {
     logger.info("UPDATE: " + sql);
 
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       con.setAutoCommit(false);
       pstmt = con.prepareStatement(sql.toString());
 
@@ -1026,8 +937,6 @@ public class Database implements StorageObject {
   *   @return boolean liefert true zurueck, wenn loeschen erfolgreich war.
    */
   public boolean delete(String id) throws StorageObjectFailure {
-    invalidatePopupCache();
-
     // ostore send notification
     if (StoreUtil.extendsStorableEntity(theEntityClass)) {
       String uniqueId = id;
@@ -1051,17 +960,21 @@ public class Database implements StorageObject {
     String sql =
       "delete from " + mainTable + " where " + primaryKeyField + "='" + id + "'";
 
-    //theLog.printInfo("DELETE " + sql);
+    logger.debug("DELETE " + sql);
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       stmt = con.createStatement();
       res = stmt.executeUpdate(sql);
-    } catch (SQLException sqe) {
+    }
+    catch (SQLException sqe) {
       throwSQLException(sqe, "delete");
-    } finally {
+    }
+    finally {
       freeConnection(con, stmt);
     }
 
+    invalidateStore();
+
     return (res > 0) ? true : false;
   }
 
@@ -1073,11 +986,7 @@ public class Database implements StorageObject {
    * @throws StorageObjectFailure
    */
   public int deleteByWhereClause(String aWhereClause) throws StorageObjectFailure {
-    invalidatePopupCache();
-    if (StoreUtil.extendsStorableEntity(theEntityClass)) {
-      StoreContainerType stoc_type = StoreContainerType.valueOf(theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST);
-      o_store.invalidate(stoc_type);
-    }
+    invalidateStore();
 
     Statement stmt = null;
     Connection con = null;
@@ -1087,7 +996,7 @@ public class Database implements StorageObject {
 
     //theLog.printInfo("DELETE " + sql);
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       stmt = con.createStatement();
       res = stmt.executeUpdate(sql);
     }
@@ -1105,15 +1014,9 @@ public class Database implements StorageObject {
   * @return immer false
    */
   public boolean delete(EntityList theEntityList) {
-    invalidatePopupCache();
-
     return false;
   }
 
-  protected void invalidatePopupCache() {
-    /** todo  invalidates toooo much */
-  }
-
   /**
    * Diese Methode fuehrt den Sqlstring <i>sql</i> aus und timed im Logfile.
    * @param stmt Statemnt
@@ -1157,8 +1060,8 @@ public class Database implements StorageObject {
     Connection connection = null;
     Statement statement = null;
     try {
-      List result = new Vector();
-      connection = getPooledCon();
+      List result = new ArrayList();
+      connection = obtainConnection();
       statement = connection.createStatement();
       ResultSet resultset = executeSql(statement, sql);
       try {
@@ -1224,7 +1127,7 @@ public class Database implements StorageObject {
 
     String useTable = mainTable;
     if (mainTablePrefix!=null && mainTablePrefix.trim().length()>0) {
-          useTable+=" "+mainTablePrefix;
+      useTable+=" "+mainTablePrefix;
     }
     StringBuffer countSql =
       new StringBuffer("select count(*) from ").append(useTable);
@@ -1246,7 +1149,7 @@ public class Database implements StorageObject {
     int result = 0;
 
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       stmt = con.createStatement();
 
       ResultSet rs = executeSql(stmt, countSql.toString());
@@ -1292,7 +1195,7 @@ public class Database implements StorageObject {
     PreparedStatement pstmt = null;
 
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       pstmt = con.prepareStatement(sql);
       result = pstmt.executeUpdate();
     }
@@ -1309,87 +1212,77 @@ public class Database implements StorageObject {
   }
 
   /**
-   * Wertet ResultSetMetaData aus und setzt interne Daten entsprechend
-   * @param md ResultSetMetaData
+   * Processes the metadata for the table this Database object is responsible for.
    */
-  private void evalMetaData(ResultSetMetaData md) throws StorageObjectFailure {
-    this.evaluatedMetaData = true;
-    this.metadataFields = new ArrayList();
-    this.metadataLabels = new ArrayList();
-    this.metadataNotNullFields = new ArrayList();
+  private void processMetaData(ResultSetMetaData aMetaData) throws StorageObjectFailure {
+    fieldNames = new ArrayList();
 
     try {
-      int numFields = md.getColumnCount();
-      this.metadataTypes = new int[numFields];
-
-      String aField;
-      int aType;
+      int numFields = aMetaData.getColumnCount();
+      fieldTypes = new int[numFields];
 
       for (int i = 1; i <= numFields; i++) {
-        aField = md.getColumnName(i);
-        metadataFields.add(aField);
-        metadataLabels.add(md.getColumnLabel(i));
-        aType = md.getColumnType(i);
-        metadataTypes[i - 1] = aType;
-
-        if (aField.equals(primaryKeyField)) {
-        }
-
-        if (md.isNullable(i) == ResultSetMetaData.columnNullable) {
-          metadataNotNullFields.add(aField);
-        }
+        fieldNames.add(aMetaData.getColumnName(i));
+        fieldTypes[i - 1] = aMetaData.getColumnType(i);
       }
     }
     catch (SQLException e) {
-      throwSQLException(e, "evalMetaData");
+      throwSQLException(e, "processMetaData");
     }
   }
 
   /**
-   *  Wertet die Metadaten eines Resultsets fuer eine Tabelle aus,
-   *  um die alle Columns und Typen einer Tabelle zu ermitteln.
+   * Retrieves metadata from the table this Database object represents
    */
-  private void get_meta_data() throws StorageObjectFailure {
-    Connection con = null;
-    PreparedStatement pstmt = null;
+  private void retrieveMetaData() throws StorageObjectFailure {
+    Connection connection = null;
+    PreparedStatement statement = null;
     String sql = "select * from " + mainTable + " where 0=1";
 
     try {
-      con = getPooledCon();
-      pstmt = con.prepareStatement(sql);
+      connection = obtainConnection();
+      statement = connection.prepareStatement(sql);
 
       logger.debug("METADATA: " + sql);
-      ResultSet rs = pstmt.executeQuery();
-      evalMetaData(rs.getMetaData());
-      rs.close();
+      ResultSet resultSet = statement.executeQuery();
+      try {
+        processMetaData(resultSet.getMetaData());
+      }
+      finally {
+        resultSet.close();
+      }
     }
     catch (SQLException e) {
-      throwSQLException(e, "get_meta_data");
+      throwSQLException(e, "retrieveMetaData");
     }
     finally {
-      freeConnection(con, pstmt);
+      freeConnection(connection, statement);
     }
   }
 
-  public Connection getPooledCon() throws StorageObjectFailure {
-    Connection con = null;
-
+  public Connection obtainConnection() throws StorageObjectFailure {
     try {
-      con = SQLManager.getInstance().requestConnection();
+      return MirGlobal.getDatabaseEngine().obtainConnection();
     }
-    catch (SQLException e) {
-      logger.error("could not connect to the database " + e.getMessage());
-
-      throw new StorageObjectFailure("Could not connect to the database", e);
+    catch (Exception e) {
+      throw new StorageObjectFailure(e);
     }
-
-    return con;
   }
 
-  public void freeConnection(Connection con, Statement stmt)
-    throws StorageObjectFailure {
-    SQLManager.closeStatement(stmt);
-    SQLManager.getInstance().returnConnection(con);
+  public void freeConnection(Connection aConnection, Statement aStatement) throws StorageObjectFailure {
+    try {
+      aStatement.close();
+    }
+    catch (Throwable t) {
+      logger.warn("Can't close statemnet: " + t.toString());
+    }
+
+    try {
+      MirGlobal.getDatabaseEngine().releaseConnection(aConnection);
+    }
+    catch (Throwable t) {
+      logger.warn("Can't release connection: " + t.toString());
+    }
   }
 
   /**
@@ -1439,4 +1332,125 @@ public class Database implements StorageObject {
     logger.error(aMessage);
     throw new StorageObjectFailure(aMessage, null);
   }
+
+  /**
+   * Invalidates any cached entity list
+   */
+  private void invalidateStore() {
+    // invalidating all EntityLists corresponding with theEntityClass
+    if (StoreUtil.extendsStorableEntity(theEntityClass)) {
+      StoreContainerType stoc_type =
+        StoreContainerType.valueOf(theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST);
+      o_store.invalidate(stoc_type);
+    }
+  }
+
+  /**
+   * Retrieves a binary value
+   */
+  public InputStream getBinaryField(String aQuery) throws StorageObjectFailure, SQLException {
+    Connection connection=null;
+    Statement statement=null;
+    InputStream inputStream;
+    InputStream imageInputStream = null;
+
+    try {
+      connection = obtainConnection();
+      try {
+        connection.setAutoCommit(false);
+        statement = connection.createStatement();
+        ResultSet resultSet = executeSql(statement, aQuery);
+
+        if(resultSet!=null) {
+          if (resultSet.next()) {
+            inputStream = resultSet.getBlob(1).getBinaryStream();
+            imageInputStream = new BinaryFieldInputStream(inputStream, connection, statement);
+          }
+          resultSet.close();
+        }
+      }
+      finally {
+      }
+    }
+    catch (Throwable t) {
+      logger.error("EntityImages.getImage failed: " + t.toString());
+      t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+
+      try {
+        connection.setAutoCommit(true);
+      }
+      catch (Throwable e) {
+        logger.error("EntityImages.getImage resetting transaction mode failed: " + e.toString());
+        e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+      }
+
+      try {
+        freeConnection(connection, statement);
+      }
+      catch (Throwable e) {
+        logger.error("EntityImages.getImage freeing connection failed: " +e.toString());
+      }
+
+      throw new StorageObjectFailure(t);
+    }
+
+    return imageInputStream;
+  }
+
+  /**
+   * Sets a binary value. The query is supposed to contain 1 ? denoting where the
+   * binary value should be inserted.
+   *
+   * e.g. <code>update images set image_data = ? where id= 22</code>
+   */
+  public void setBinaryField(String aQuery, byte aData[]) throws StorageObjectFailure, SQLException {
+    PreparedStatement statement = null;
+    Connection connection = obtainConnection();
+    try {
+      connection.setAutoCommit(false);
+      try {
+        statement = connection.prepareStatement(aQuery);
+        statement.setBinaryStream(1, new ByteArrayInputStream(aData), aData.length);
+        statement.execute();
+        connection.commit();
+      }
+      finally {
+        connection.setAutoCommit(true);
+      }
+    }
+    finally {
+      freeConnection(connection, statement);
+    }
+  }
+
+  /**
+   * a small wrapper class that allows us to store the DB connection resources
+   * that the BlobInputStream is using and free them upon closing of the stream
+   */
+  private class BinaryFieldInputStream extends InputStream {
+    InputStream inputStream;
+    Connection connection;
+    Statement statement;
+
+    public BinaryFieldInputStream(InputStream aBlobInputStream, Connection aConnection, Statement aStatement ) {
+      inputStream = aBlobInputStream;
+      connection = aConnection;
+      statement = aStatement;
+    }
+
+    public void close () throws IOException {
+      inputStream.close();
+      try {
+        connection.setAutoCommit(true);
+        freeConnection(connection, statement);
+      }
+      catch (Exception e) {
+        throw new IOException("close(): "+e.toString());
+      }
+    }
+
+    public int read() throws IOException {
+      return inputStream.read();
+    }
+  }
 }
index 62617e2..5f4ecc9 100755 (executable)
@@ -35,6 +35,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.List;
 import java.util.Map;
+import java.io.InputStream;
 
 import mir.entity.Entity;
 import mir.entity.EntityList;
@@ -65,11 +66,10 @@ public interface StorageObject {
    */
   public int deleteByWhereClause(String aWhereClause) throws StorageObjectFailure;
 
-  public List getFields() throws StorageObjectFailure;
-
-  public int[] getTypes() throws StorageObjectFailure;
-
-  public List getLabels() throws StorageObjectFailure;
+  /**
+   * Returns a list of field names for this <code>StorageObject</code>
+   */
+  public List getFieldNames() throws StorageObjectFailure;
 
   public void update(Entity a) throws StorageObjectFailure;
 
@@ -81,7 +81,7 @@ public interface StorageObject {
 
   public String getTableName();
 
-  public Connection getPooledCon() throws StorageObjectFailure;
+  public Connection obtainConnection() throws StorageObjectFailure;
 
   public ResultSet executeSql(Statement a, String sql) throws StorageObjectFailure, SQLException;
 
@@ -113,4 +113,7 @@ public interface StorageObject {
 
   public int getSize(String mainTablePrefix, List extraTables, String where) throws SQLException, StorageObjectFailure;
 
+  public InputStream getBinaryField(String aQuery) throws SQLException, StorageObjectFailure;
+
+  public void setBinaryField(String aQuery, byte aData[]) throws StorageObjectFailure, SQLException;
 }
index f84206d..0c65b1c 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.storage.store;
@@ -59,14 +59,10 @@ package mir.storage.store;
  * @version 1.0
  */
 
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.MissingResourceException;
-import java.util.Properties;
-
 import javax.servlet.http.HttpServletRequest;
 
 import mir.config.MirPropertiesConfiguration;
@@ -77,28 +73,12 @@ public class ObjectStore {
   private final static ObjectStore INSTANCE = new ObjectStore();
   private final static Map containerMap = new HashMap(); // StoreContainerType/StoreContainer
   private static long storeHit = 0, storeMiss = 0;
-  private Properties ostoreConf;
+  private MirPropertiesConfiguration configuration;
   private LoggerWrapper logger;
 
   private ObjectStore() {
-    String confName = null;
-
     logger = new LoggerWrapper("Database.ObjectStore");
-    Properties conf = new Properties();
-
-    try {
-      confName =
-          MirPropertiesConfiguration.instance().getString("Home") +
-          "etc/objectstore.properties";
-      conf.load(new BufferedInputStream(new FileInputStream(confName)));
-    }
-    catch (java.io.FileNotFoundException fnfe) {
-      logger.error("could not read config file. not found: " + confName);
-    }
-    catch (Throwable t) {
-      logger.error("could not get config: " + t.getMessage());
-    }
-    ostoreConf = conf;
+    configuration = MirPropertiesConfiguration.instance();
   }
 
   public static ObjectStore getInstance() {
@@ -165,14 +145,11 @@ public class ObjectStore {
   }
 
   /**
-   *  Method:       invalidate(StoreContainerType)
-   *  Description:  serves to invalidate a whole StoreContainer
-   *
-   *  @return
+   * serves to invalidate a whole StoreContainer
    */
   public void invalidate(StoreContainerType stoc_type) {
     if (stoc_type != null) {
-      /** @todo invalidates too much:
+      /*  @todo invalidates too much:
        *  improvement: if instanceof StoreContainerEntity && EntityList
        *  then invalidate only StoreIdentifier matching the right table
        */
@@ -215,9 +192,8 @@ public class ObjectStore {
 
   public String getConfProperty(String name) {
     if (name != null) {
-      String returnValue = "";
       try {
-        return ostoreConf.getProperty(name);
+        return configuration.getString(name);
       }
       catch (MissingResourceException e) {
         logger.error("getConfProperty: " + e.toString());
index 917ceb9..f1717e2 100755 (executable)
@@ -78,21 +78,7 @@ public final class StoreUtil {
    * @return true if yes, otherwise no.
    */
   public static final boolean extendsStorableEntity(Class aClass) {
-     if (aClass != null) {
-       if (aClass == StorableObjectEntity.class) return true;
-        Class superclass = aClass.getSuperclass();
-
-        if (superclass != null) {
-           if (superclass == StorableObjectEntity.class) {
-              return true;
-           }
-           else {
-              return extendsStorableEntity(superclass);
-           }
-        }
-     }
-
-     return false;
+    return StorableObjectEntity.class.isAssignableFrom(aClass);
   }
 
 
index 1edf779..5b6b2a3 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.util;
@@ -32,6 +32,7 @@ package mir.util;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Vector;
+import java.util.ArrayList;
 
 public class CachingRewindableIterator implements RewindableIterator {
   private Iterator master;
@@ -40,7 +41,7 @@ public class CachingRewindableIterator implements RewindableIterator {
 
   public CachingRewindableIterator(Iterator anIterator) {
     master = anIterator;
-    cachedItems = new Vector();
+    cachedItems = new ArrayList();
     iterationPosition = 0;
   }
 
index 218213e..d831028 100755 (executable)
@@ -30,6 +30,9 @@
 package mir.util;
 
 import java.lang.reflect.InvocationTargetException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 
 import multex.Failure;
 
@@ -53,7 +56,6 @@ public class ExceptionFunctions {
    * Traces an exception to it's root cause, using all known exception types that support
    *   cause exceptions.
    *
-   * @param anException
    * @return the cause (if found)
    */
 
@@ -76,4 +78,13 @@ public class ExceptionFunctions {
 
     return result;
   }
+
+  /**
+   * Prints an exception's stacktrace to a <code>String</code> 
+   */
+  public static String getStackTrace(Throwable aThrowable) {
+    StringWriter writer = new StringWriter();
+    aThrowable.printStackTrace(new PrintWriter(writer));
+    return writer.toString();
+  }
 }
index bbbaa68..c9e6a10 100755 (executable)
  */
 package mir.util;
 
-import gnu.regexp.RE;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
+import java.io.*;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
-import java.util.Vector;
+
+import gnu.regexp.RE;
 
 public class FileFunctions {
   protected static final int FILE_COPY_BUFFER_SIZE = 65536;
@@ -115,6 +109,46 @@ public class FileFunctions {
     }
   }
 
+  /**
+   * Copy the contents of an {@link InputStream} to a {@link File}
+   */
+  public static void copy(InputStream aSource, File aDestination) throws IOException {
+    BufferedOutputStream outputStream =
+        new BufferedOutputStream(new FileOutputStream(aDestination), 8192);
+
+    int read;
+    byte[] buf = new byte[8 * 1024];
+
+    while ((read = aSource.read(buf)) != -1) {
+      outputStream.write(buf, 0, read);
+    }
+
+    aSource.close();
+    outputStream.close();
+  }
+
+  /**
+   * Moves a {@link File} to a new location
+   */
+  public static void move(File aSource, File aDestination) throws IOException {
+    aDestination.getParentFile().mkdirs();
+    if (!aSource.renameTo(aDestination)) {
+      byte[] buffer = new byte[16384];
+      FileInputStream inputStream = new FileInputStream(aSource);
+      FileOutputStream outputStream = new FileOutputStream(aDestination);
+      try {
+        while (inputStream.read(buffer)>0) {
+          outputStream.write(buffer);
+        }
+      }
+      finally {
+        outputStream.close();
+        inputStream.close();
+      }
+      aSource.delete();
+    };
+  }
+
   public static class RegExpFileFilter implements FilenameFilter {
     private RE expression;
 
@@ -139,16 +173,36 @@ public class FileFunctions {
     public boolean accept(File aDir, String aName) {
       return new File(aDir, aName).isDirectory();
     }
-
   }
 
   public static List getDirectoryContentsAsList(File aDirectory, FilenameFilter aFilter) {
     Object[] contents = aDirectory.list(aFilter);
     if (contents==null)
-      return new Vector();
+      return Collections.EMPTY_LIST;
     else
       return Arrays.asList(contents);
   }
 
+  public static String getExtension(String aPath) {
+    int position = aPath.lastIndexOf('.');
+    if (position>=0) {
+      return aPath.substring(position+1);
+    }
+    else {
+      return "";
+    }
+  }
+
+  public static boolean isAbsolutePath(String aPath) {
+    return new File(aPath).isAbsolute();
+  }
 
+  public static File getAbsoluteOrRelativeFile(File aParentIfRelative, String aPath) {
+    if (isAbsolutePath(aPath)) {
+      return new File(aPath);
+    }
+    else {
+      return new File(aParentIfRelative, aPath);
+    }
+  }
 }
\ No newline at end of file
index e535f1a..d7d88be 100755 (executable)
@@ -42,7 +42,7 @@ public class GeneratorDateTimeFunctions {
   private GeneratorDateTimeFunctions() {
   }
 
-  public static class FormatDateFunction implements Generator.GeneratorFunction {
+  public static class FormatDateFunction implements Generator.Function {
     private String defaultTimezone;
 
     public FormatDateFunction(String aDefaultTimeZone) {
@@ -96,13 +96,13 @@ public class GeneratorDateTimeFunctions {
 
   public static class DateTimeFunctions  {
     private String defaultTimezone;
-    private Generator.GeneratorFunction formatDate;
+    private Generator.Function formatDate;
 
     public DateTimeFunctions(String aDefaultTimezone) {
       defaultTimezone = aDefaultTimezone;
     }
 
-    public Generator.GeneratorFunction getFormatDate() {
+    public Generator.Function getFormatDate() {
       if (formatDate == null) {
         formatDate = new FormatDateFunction(defaultTimezone);
       }
diff --git a/source/mir/util/GeneratorExpressionFunctions.java b/source/mir/util/GeneratorExpressionFunctions.java
deleted file mode 100755 (executable)
index 1cec25d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.util;
-
-import java.util.List;
-import java.util.Map;
-
-import mir.generator.Generator;
-import mir.generator.GeneratorExc;
-import mir.generator.GeneratorFailure;
-
-public class GeneratorExpressionFunctions {
-  private GeneratorExpressionFunctions() {
-  }
-
-  public static class evaluateExpressionFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=2)
-          throw new GeneratorExc("evaluateExpressionFunction <map> <expression>: 2 parameters expected");
-
-        Object parameter1=aParameters.get(0);
-
-        if (!(parameter1 instanceof Map))
-          throw new GeneratorExc("evaluateExpressionFunction <map> <expression>: first parameter must be a map");
-
-        return ParameterExpander.expandExpression((Map) parameter1, StringRoutines.interpretAsString(aParameters.get(1)));
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure("encodeURIGeneratorFunction: " + t.getMessage(), t);
-      }
-    };
-  }
-
-
-
-}
\ No newline at end of file
index 2da18e5..becea34 100755 (executable)
@@ -54,11 +54,11 @@ public class GeneratorFormatAdapters {
       value = aValue;
     }
 
-    public Generator.GeneratorFunction getFormat() {
+    public Generator.Function getFormat() {
       return new NumberFormattingFunction();
     }
 
-    private class NumberFormattingFunction implements Generator.GeneratorFunction {
+    private class NumberFormattingFunction implements Generator.Function {
       public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
         try {
           if (aParameters.size() != 1 || ! (aParameters.get(0)instanceof String))
@@ -106,7 +106,7 @@ public class GeneratorFormatAdapters {
       return defaultTimezone;
     }
 
-    public Generator.GeneratorFunction getFormat() {
+    public Generator.Function getFormat() {
       return new DateFormattingFunction();
     }
 
@@ -118,7 +118,7 @@ public class GeneratorFormatAdapters {
       return value;
     }
 
-    private class DateFormattingFunction implements Generator.GeneratorFunction {
+    private class DateFormattingFunction implements Generator.Function {
       public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
         try {
           if (aParameters.size() < 1 || aParameters.size() > 2 ||
diff --git a/source/mir/util/GeneratorHTMLFunctions.java b/source/mir/util/GeneratorHTMLFunctions.java
deleted file mode 100755 (executable)
index bcedf17..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License,
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
- * (or with modified versions of the above that use the same license as the above),
- * and distribute linked combinations including the two.  You must obey the
- * GNU General Public License in all respects for all of the code used other than
- * the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.util;
-
-import java.util.List;
-
-import mir.generator.Generator;
-import mir.generator.GeneratorExc;
-import mir.generator.GeneratorFailure;
-
-public class GeneratorHTMLFunctions {
-  private GeneratorHTMLFunctions() {}
-
-  public static class encodeURIGeneratorFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()<1 || aParameters.size()>2)
-          throw new GeneratorExc("encodeURIGeneratorFunction <text> [<encoding>]: only 1 or 2 parameters expected");
-
-        if (aParameters.size()>=2)
-          return HTMLRoutines.encodeURL(StringRoutines.interpretAsString(aParameters.get(0)), (StringRoutines.interpretAsString(aParameters.get(1))));
-        else
-          return HTMLRoutines.encodeURL(StringRoutines.interpretAsString(aParameters.get(0)));
-
-
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure("encodeURIGeneratorFunction: " + t.getMessage(), t);
-      }
-    };
-  }
-
-  public static class encodeHTMLGeneratorFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc {
-      try {
-        if (aParameters.size()!=1)
-          throw new GeneratorExc("encodeHTMLGeneratorFunction: only 1 parameter expected");
-
-        return HTMLRoutines.encodeHTML(StringRoutines.interpretAsString(aParameters.get(0)));
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure("encodeHTMLGeneratorFunction: " + t.getMessage(), t);
-      }
-    };
-  }
-
-  public static class prettyEncodeHTMLGeneratorFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc {
-      try {
-        if (aParameters.size()!=1)
-          throw new GeneratorExc("prettyEncodeHTMLGeneratorFunction: only 1 parameter expected");
-
-        return HTMLRoutines.prettyEncodeHTML(StringRoutines.interpretAsString(aParameters.get(0)));
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure("prettyEncodeHTMLGeneratorFunction: " + t.getMessage(), t);
-      }
-    };
-  }
-
-  public static class encodeXMLGeneratorFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc {
-      try {
-        if (aParameters.size()!=1)
-          throw new GeneratorExc("encodeHTMLGeneratorFunction: only 1 parameter expected");
-
-        return HTMLRoutines.encodeXML(StringRoutines.interpretAsString(aParameters.get(0)));
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure("encodeHTMLGeneratorFunction: " + t.getMessage(), t);
-      }
-    };
-  }
-}
diff --git a/source/mir/util/GeneratorIntegerFunctions.java b/source/mir/util/GeneratorIntegerFunctions.java
deleted file mode 100755 (executable)
index e323866..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.util;
-
-import java.util.List;
-
-import mir.generator.Generator;
-import mir.generator.GeneratorExc;
-import mir.generator.GeneratorFailure;
-
-public class GeneratorIntegerFunctions {
-
-  private GeneratorIntegerFunctions() {}
-
-  public static class incrementFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      int incrementValue = 1;
-
-      try {
-        if (aParameters.size()>2 || aParameters.size()<1)
-          throw new GeneratorExc("incrementFunction: 1 or 2 parameters expected: value [increment value]");
-
-        if (aParameters.size()>1)
-          incrementValue = StringRoutines.interpretAsInteger(aParameters.get(1));
-
-        return new Integer(StringRoutines.interpretAsInteger(aParameters.get(0)) + incrementValue);
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure("incrementFunction: " + t.getMessage(), t);
-      }
-    };
-  }
-
-  public static class isOddFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=1)
-          throw new GeneratorExc("isOddFunction: 1 parameters expected: value");
-
-        return new Boolean((StringRoutines.interpretAsInteger(aParameters.get(0)) & 1) == 1);
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure("isOddFunction: " + t.getMessage(), t);
-      }
-    };
-  }
-}
\ No newline at end of file
diff --git a/source/mir/util/GeneratorListFunctions.java b/source/mir/util/GeneratorListFunctions.java
deleted file mode 100755 (executable)
index dcb8614..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License,
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
- * (or with modified versions of the above that use the same license as the above),
- * and distribute linked combinations including the two.  You must obey the
- * GNU General Public License in all respects for all of the code used other than
- * the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.util;
-
-import java.util.List;
-import java.util.Vector;
-
-import mir.generator.Generator;
-import mir.generator.GeneratorExc;
-import mir.generator.GeneratorFailure;
-
-public class GeneratorListFunctions {
-  private GeneratorListFunctions() {}
-
-  public static class subListFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        int skip;
-        int maxSize;
-
-        if (aParameters.size()>3 || aParameters.size()<2)
-          throw new GeneratorExc("iteratorSubsetFunction: 2 or 3 parameters expected");
-        if (aParameters.get(0)==null)
-          return "";
-
-        if (!(aParameters.get(0) instanceof RewindableIterator) && !(aParameters.get(0) instanceof List))
-          throw new GeneratorExc("iteratorSubsetFunction: first parameter must be a RewindableIterator (not a "+aParameters.get(0).getClass().getName()+")");
-
-        skip = StringRoutines.interpretAsInteger(aParameters.get(1));
-        if (aParameters.size()>=2)
-          maxSize = StringRoutines.interpretAsInteger(aParameters.get(2));
-        else
-          maxSize = -1;
-
-
-        if ((aParameters.get(0) instanceof RewindableIterator))
-          return new SubsetIterator((RewindableIterator) aParameters.get(0), skip, maxSize);
-        else {
-          List list = (List) aParameters.get(0);
-
-          if (skip>=list.size())
-            return new Vector();
-          if (maxSize<0 || (skip+maxSize)>=list.size())
-            return list.subList(skip, list.size());
-          else
-            return list.subList(skip, skip+maxSize);
-        }
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (GeneratorFailure e) {
-        throw e;
-      }
-      catch (Throwable e) {
-        throw new GeneratorFailure(e);
-      }
-    };
-  }
-
-  public static class listSizeFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=1)
-          throw new GeneratorExc("listSizeFunction: 1 parameter expected");
-        if (aParameters.get(0)==null)
-          return "";
-
-        if (!(aParameters.get(0) instanceof RewindableIterator) && !(aParameters.get(0) instanceof List))
-          throw new GeneratorExc("listSizeFunction: first parameter must be a RewindableIterator (not a "+aParameters.get(0).getClass().getName()+")");
-
-        if ((aParameters.get(0) instanceof RewindableIterator)) {
-          RewindableIterator iterator = (RewindableIterator) aParameters.get(0);
-          iterator.rewind();
-          int result=0;
-          while (iterator.hasNext()) {
-            result++;
-            iterator.next();
-          }
-
-          iterator.rewind();
-          return new Integer(result);
-        }
-        else {
-          List list = (List) aParameters.get(0);
-          return new Integer(list.size());
-        }
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (GeneratorFailure e) {
-        throw e;
-      }
-      catch (Throwable e) {
-        throw new GeneratorFailure(e);
-      }
-    };
-  }
-}
diff --git a/source/mir/util/GeneratorRegularExpressionFunctions.java b/source/mir/util/GeneratorRegularExpressionFunctions.java
deleted file mode 100755 (executable)
index 67d95cb..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.util;
-
-import java.util.List;
-
-import mir.generator.Generator;
-import mir.generator.GeneratorExc;
-import mir.generator.GeneratorFailure;
-
-public class GeneratorRegularExpressionFunctions {
-
-  private GeneratorRegularExpressionFunctions() {}
-
-  public static class regularExpressionReplaceFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=3)
-          throw new GeneratorExc("regularExpressionReplaceFunction: exactly 3 parameters expected: data, search expression, replacement");
-        if (aParameters.get(0)==null)
-          return "";
-        if (!(aParameters.get(0) instanceof String) || !(aParameters.get(1) instanceof String)  || !(aParameters.get(2) instanceof String))
-          throw new GeneratorExc("regularExpressionReplaceFunction: parameters must be strings");
-
-        return StringRoutines.performRegularExpressionReplacement((String) aParameters.get(0), (String) aParameters.get(1), (String) aParameters.get(2));
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure(t);
-      }
-    };
-  }
-  public static class regularExpressionMatchFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=2)
-          throw new GeneratorExc("regularExpressionMatchFunction: exactly 2 parameters expected: data, search expression");
-        if (aParameters.get(0)==null)
-          return new Boolean(false);
-        if (!(aParameters.get(0) instanceof String) || !(aParameters.get(1) instanceof String))
-          throw new GeneratorExc("regularExpressionReplaceFunction: parameters must be strings");
-
-        return new Boolean(StringRoutines.performRegularExpressionSearch((String) aParameters.get(0), (String) aParameters.get(1)));
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure(t);
-      }
-    };
-  }
-    
-    
-
-}
diff --git a/source/mir/util/GeneratorStringFunctions.java b/source/mir/util/GeneratorStringFunctions.java
deleted file mode 100755 (executable)
index 28e4a2c..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License,
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
- * (or with modified versions of the above that use the same license as the above),
- * and distribute linked combinations including the two.  You must obey the
- * GNU General Public License in all respects for all of the code used other than
- * the above mentioned libraries.  If you modify this file, you may extend this
- * exception to your version of the file, but you are not obligated to do so.
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.util;
-
-import java.util.List;
-
-import mir.generator.Generator;
-import mir.generator.GeneratorExc;
-import mir.generator.GeneratorFailure;
-
-public class GeneratorStringFunctions {
-
-  private GeneratorStringFunctions() {}
-
-  public static class subStringFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()>3 || aParameters.size()<2)
-          throw new GeneratorExc("subStringFunction: 2 or 3 parameters expected: string from [length]");
-
-        if (aParameters.size()==3) {
-          return StringRoutines.interpretAsString(aParameters.get(0)).substring(
-              StringRoutines.interpretAsInteger(aParameters.get(1)),
-              StringRoutines.interpretAsInteger(aParameters.get(2)));
-        }
-        else {
-          return StringRoutines.interpretAsString(aParameters.get(0)).substring(
-              StringRoutines.interpretAsInteger(aParameters.get(1)));
-        }
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure(t);
-      }
-    };
-  }
-
-  public static class jdbcStringEscapeFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=1 || !(aParameters.get(0) instanceof String))
-          throw new GeneratorExc("jdbcStringEscapeFunction: 1 parameter expected: string ");
-
-        return JDBCStringRoutines.escapeStringLiteral((String) aParameters.get(0));
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure(t);
-      }
-    };
-  }
-
-  public static class constructStructuredStringFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=1)
-          throw new GeneratorExc("constructStructureStringFunction: 1 parameter expected: string ");
-
-        if (aParameters.get(0)==null)
-          return StructuredContentParser.constructStringLiteral("");
-        else
-          return StructuredContentParser.constructStringLiteral("" + aParameters.get(0));
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure(t);
-      }
-    };
-  }
-
-  public static class structuredStringParserFunction implements Generator.GeneratorFunction {
-    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
-      try {
-        if (aParameters.size()!=1)
-          throw new GeneratorExc("constructStructureStringFunction: 1 parameter expected: string ");
-
-        if (aParameters.get(0)==null)
-          return null;
-        else
-          return StructuredContentParser.parse("" + aParameters.get(0));
-      }
-      catch (GeneratorExc e) {
-        throw e;
-      }
-      catch (Throwable t) {
-        throw new GeneratorFailure(t);
-      }
-    };
-  }
-}
\ No newline at end of file
diff --git a/source/mir/util/HTTPClientHelper.java b/source/mir/util/HTTPClientHelper.java
new file mode 100755 (executable)
index 0000000..666f4cf
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+
+package mir.util;
+
+
+import java.io.InputStream;
+import java.io.IOException;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+
+import mir.util.UtilExc;
+
+public class HTTPClientHelper {
+  private HttpClient client;
+  private HttpMethod method;
+  
+  public HTTPClientHelper() {
+      client = new HttpClient();
+      client.setConnectionTimeout(5000);
+      client.setTimeout(5000);
+  }
+
+
+  public InputStream getUrl(String anUrl) throws UtilExc{
+    try{
+      method = new GetMethod(anUrl);
+      method.setFollowRedirects(true);
+      method.setStrictMode(false);
+      client.executeMethod(method);
+      InputStream inputStream  = method.getResponseBodyAsStream();
+      return inputStream;
+    }
+    catch (IOException e){
+       throw new UtilExc(e.getMessage());
+    }
+  }
+  
+  public void releaseHTTPConnection() {
+    method.releaseConnection();
+    method.recycle();
+  }
+
+}
index 3ca02f1..3d9d96f 100755 (executable)
  */
 package mir.util;
 
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
-import javax.servlet.http.HttpServletRequest;
-
 import mir.log.LoggerWrapper;
-
+import org.apache.commons.fileupload.DiskFileUpload;
 import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileUpload;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
 
 public class HTTPParsedRequest {
   static final String MULTIPART_FORMDATA_CONTENTTYPE = "multipart/form-data";
@@ -52,23 +44,21 @@ public class HTTPParsedRequest {
   private int maxUploadSize;
   private String tempDir;
 
-  private Map stringValues;
-  private Map listValues;
+  private Map parameterStringValues;
+  private Map parameterListValues;
   private List files;
 
-  private LoggerWrapper logger;
+  private LoggerWrapper logger = new LoggerWrapper("Utility.HTTPParsedRequest");
 
   public HTTPParsedRequest(HttpServletRequest aRequest, String anEncoding, int aMaxUploadSize, String aTempDir) throws UtilExc, UtilFailure {
-    logger = new LoggerWrapper("Utility.HTTPParsedRequest");
-
     request = aRequest;
     encoding = anEncoding;
     maxUploadSize = aMaxUploadSize;
     tempDir = aTempDir;
 
-    stringValues = new HashMap();
-    listValues = new HashMap();
-    files = new Vector();
+    parameterStringValues = new HashMap();
+    parameterListValues = new HashMap();
+    files = new ArrayList();
 
     parseRequest(aRequest);
   }
@@ -82,7 +72,11 @@ public class HTTPParsedRequest {
   }
 
   public String getParameter(String aName) {
-    return (String) stringValues.get(aName);
+    return (String) parameterStringValues.get(aName);
+  }
+
+  public Collection getParameterNames() {
+    return parameterStringValues.keySet();
   }
 
   public String getHeader(String aName) {
@@ -94,10 +88,10 @@ public class HTTPParsedRequest {
   }
 
   public List getParameterList(String aName) {
-    if (listValues.containsKey(aName))
-      return (List) listValues.get(aName);
+    if (parameterListValues.containsKey(aName))
+      return (List) parameterListValues.get(aName);
     else
-      return new Vector();
+      return Collections.EMPTY_LIST;
   }
 
   protected void parseRequest(HttpServletRequest aRequest) throws UtilExc, UtilFailure {
@@ -111,9 +105,9 @@ public class HTTPParsedRequest {
       while (e.hasMoreElements()) {
         String name = (String) e.nextElement();
 
-        stringValues.put(name, aRequest.getParameter(name));
-        List listValue = new Vector(Arrays.asList(aRequest.getParameterValues(name)));
-        listValues.put(name, listValue);
+        parameterStringValues.put(name, aRequest.getParameter(name));
+        List listValue = new ArrayList(Arrays.asList(aRequest.getParameterValues(name)));
+        parameterListValues.put(name, listValue);
       }
 
       if (parts.size()>0 && ((String) parts.get(0)).trim().toLowerCase().equals(MULTIPART_FORMDATA_CONTENTTYPE)) {
@@ -129,10 +123,11 @@ public class HTTPParsedRequest {
 
   protected void parseMultipartRequest() throws UtilExc, UtilFailure {
     try {
-      FileUpload upload = new FileUpload();
+      DiskFileUpload upload = new DiskFileUpload();
 
+      upload.setSizeThreshold(100000);
       upload.setSizeMax(maxUploadSize);
-      upload.setSizeThreshold(4096);
+      upload.setHeaderEncoding(encoding);
       upload.setRepositoryPath(tempDir);
 
       List items = upload.parseRequest(request);
@@ -142,14 +137,14 @@ public class HTTPParsedRequest {
         FileItem item = (FileItem) i.next();
 
         if (item.isFormField()) {
-          if (!stringValues.containsKey(item.getName())) {
-            stringValues.put(item.getFieldName(), item.getString(encoding));
+          if (!parameterStringValues.containsKey(item.getName())) {
+            parameterStringValues.put(item.getFieldName(), item.getString(encoding));
           }
 
-          List listValue = (List) listValues.get(item.getFieldName());
+          List listValue = (List) parameterListValues.get(item.getFieldName());
           if (listValue == null) {
-            listValue = new Vector();
-            listValues.put(item.getFieldName(), listValue);
+            listValue = new ArrayList();
+            parameterListValues.put(item.getFieldName(), listValue);
           }
           listValue.add(item.getString(encoding));
         }
index 60df288..9b50247 100755 (executable)
@@ -30,9 +30,8 @@
 
 package mir.util;
 
+import java.util.ArrayList;
 import java.util.List;
-import java.util.Vector;
-
 import javax.servlet.http.HttpServletRequest;
 
 public class HTTPRequestParser {
@@ -79,7 +78,7 @@ public class HTTPRequestParser {
 
   public List getParameterList(String aName) {
     try {
-      List result = new Vector();
+      List result = new ArrayList();
       String items[] = request.getParameterValues(aName);
 
       if (items!=null) {
index 2dd057b..2260d4d 100755 (executable)
 package mir.util;
 
 import java.util.List;
+import java.net.InetAddress;
 
 public class InternetFunctions {
   private InternetFunctions() {
   }
 
   public static boolean isIpAddressInNetwork(String anIpAddress, String aNetwork) throws Exception {
-    long ipAddress = parseIPAddress(anIpAddress);
+    long ipAddress = parseHostNameOrIPAddress(anIpAddress);
     long network = 0;
     long netMask = (1L<<32)-1;
     List networkParts = StringRoutines.separateString(aNetwork, "/");
 
-    network = parseIPAddress((String) networkParts.get(0));
+    network = parseHostNameOrIPAddress((String) networkParts.get(0));
     if (networkParts.size()>=2) {
       netMask=parseNetmask((String) networkParts.get(1));
     }
@@ -51,6 +52,15 @@ public class InternetFunctions {
     return (ipAddress & netMask ) == (network & netMask);
   }
 
+  public static long parseHostNameOrIPAddress(String aHostName) throws Exception {
+    InetAddress addr = InetAddress.getByName(aHostName.trim());
+    return
+        ((((long) addr.getAddress()[0])&255) << 24) +
+        ((((long) addr.getAddress()[1])&255) << 16) +
+        ((((long) addr.getAddress()[2])&255) << 8) +
+        ((((long) addr.getAddress()[3])&255));
+  }
+
   public static long parseIPAddress(String anIpAddress) throws Exception {
     int[] parts = {0,0,0,0};
     int i;
@@ -61,7 +71,7 @@ public class InternetFunctions {
 
     try {
       for (i=0; i<4; i++) {
-        parts[i] = Integer.parseInt((String) stringParts.get(i));
+        parts[i] = Integer.parseInt(((String) stringParts.get(i)).trim());
       }
     }
     catch (Throwable t) {
@@ -93,4 +103,5 @@ public class InternetFunctions {
 
     return (1L<<32)-1;
   }
+
 }
\ No newline at end of file
index 769f6fb..734bec9 100755 (executable)
@@ -42,10 +42,40 @@ import multex.Exc;
 import org.apache.commons.beanutils.MethodUtils;
 import org.apache.commons.beanutils.PropertyUtils;
 
+/**
+ * Class to work with expressions. Will be gradually phased out and replaced
+ * with {@link mir.util.expressions.ExpressionParser}
+ */
 public class ParameterExpander {
   final static String NODE_SEPARATOR = ".";
   final static char STRING_ESCAPE_CHARACTER = '\\';
 
+  /**
+   * Fundamental method to retrieve a field of an object. Supported are
+   *  maps, beans and objects with a generic get method  
+   */
+  public static Object getObjectField(Object anObject, Object aField) {
+    if (anObject instanceof Map) {
+      return ((Map) anObject).get(aField);
+    }
+    else if ((aField instanceof String) && PropertyUtils.isReadable(anObject, (String) aField)) {
+      try {
+        return PropertyUtils.getProperty(anObject, (String) aField);
+      }
+      catch (Throwable t) {
+        throw new RuntimeException(t.getMessage());
+      }
+    }
+    else {
+      try {
+        return MethodUtils.invokeExactMethod(anObject, "get", aField);
+      }
+      catch (Throwable t) {
+        throw new RuntimeException("Invalid reference of " + aField + " into " + anObject);
+      }
+    }
+  }
+
   private static Object findNode(String aKey, Map aMap, List aParts, boolean aMakeIfNotPresent) throws Exception {
     Iterator i;
     String location = "";
@@ -74,7 +104,7 @@ public class ParameterExpander {
           ((Map) node).put(part, newNode);
         }
         else
-          throw new ParameterExpanderExc( "Can't expand key {1}: {2} does not exist", new Object[]{aKey,location} );
+          throw new ParameterExpanderExc( "Can't expand key " + aKey + ": " + location + " does not exist");
 
       node = newNode;
     }
@@ -95,7 +125,7 @@ public class ParameterExpander {
     Object expandedValue = findValueForKey(aMap, aKey);
 
     if (!(expandedValue instanceof String))
-      throw new ParameterExpanderExc( "Value of key is not a string but a {1}", new Object[]{expandedValue.getClass().getName()} );
+      throw new ParameterExpanderExc( "Value of key is not a string but a " + expandedValue.getClass().getName());
 
     return (String) expandedValue;
   }
@@ -108,11 +138,12 @@ public class ParameterExpander {
 
     Object node=findNode(aKey, aMap, parts, true);
 
+    // todo: bean support
     if (node instanceof Map) {
       ((Map) node).put(key, aValue);
     }
     else
-      throw new ParameterExpanderExc( "Can't set key {1}: not inside a Map", new Object[]{aKey} );
+      throw new ParameterExpanderExc( "Can't set key " + aKey + " : not inside a Map");
   }
 
   public static String expandExpression(Object aContext, String anExpression) throws Exception {
@@ -143,7 +174,7 @@ public class ParameterExpander {
                 endOfExpressionPosition++;
               }
               if (endOfExpressionPosition>=anExpression.length()) {
-                throw new ParameterExpanderExc("Unterminated string in {1}",new Object[]{anExpression});
+                throw new ParameterExpanderExc("Unterminated string in '" +anExpression+"'");
               }
             }
             endOfExpressionPosition++;
@@ -153,7 +184,7 @@ public class ParameterExpander {
             previousPosition=endOfExpressionPosition+1;
           }
           else {
-            throw new ParameterExpanderExc("Missing } in {1}",new Object[]{anExpression});
+            throw new ParameterExpanderExc("Missing } in " + anExpression);
           }
         }
         else
@@ -573,28 +604,6 @@ public class ParameterExpander {
       return result;
     }
 
-    private Object evaluateObjectField(Object anObject, Object aField) {
-      if (anObject instanceof Map) {
-        return ((Map) anObject).get(aField);
-      }
-      else if ((aField instanceof String) && PropertyUtils.isReadable(anObject, (String) aField)) {
-        try {
-          return PropertyUtils.getProperty(anObject, (String) aField);
-        }
-        catch (Throwable t) {
-          throw new RuntimeException(t.getMessage());
-        }
-      }
-      else {
-        try {
-          return MethodUtils.invokeExactMethod(anObject, "get", aField);
-        }
-        catch (Throwable t) {
-          throw new RuntimeException("Invalid reference of " + aField + " into " + anObject);
-        }
-      }
-    }
-
     private Object parseVariable() {
       boolean done;
       Token token;
@@ -612,19 +621,19 @@ public class ParameterExpander {
           if (!(token instanceof RightSquareBraceToken))
             throw new RuntimeException("] expected");
 
-          currentValue = evaluateObjectField(currentValue, qualifier);
+          currentValue = getObjectField(currentValue, qualifier);
         }
         else if (token instanceof IdentifierToken) {
           scanner.scan();
           qualifier = ((IdentifierToken) token).getName();
 
-          currentValue = evaluateObjectField(currentValue, qualifier);
+          currentValue = getObjectField(currentValue, qualifier);
         }
         else if (token instanceof LeftParenthesisToken) {
-          if (currentValue instanceof Generator.GeneratorFunction) {
+          if (currentValue instanceof Generator.Function) {
             parameters = parseList();
             try {
-              currentValue = ((Generator.GeneratorFunction) currentValue).perform(parameters);
+              currentValue = ((Generator.Function) currentValue).perform(parameters);
             }
             catch (GeneratorExc t) {
               throw new RuntimeException(t.getMessage());
@@ -781,6 +790,22 @@ public class ParameterExpander {
       if (aValue instanceof Boolean)
         return ((Boolean) aValue).booleanValue();
 
+      if (aValue instanceof RewindableIterator) {
+        ((RewindableIterator) aValue).rewind();
+      }
+
+      if (aValue instanceof Iterator) {
+        return ((Iterator) aValue).hasNext();
+      }
+
+      if (aValue instanceof List) {
+        return ((List) aValue).size()>0;
+      }
+
+      if (aValue instanceof String) {
+        return ((String) aValue).length()>0;
+      }
+
       return aValue!=null;
     }
 
@@ -877,8 +902,8 @@ public class ParameterExpander {
   }
 
   public static class ParameterExpanderExc extends Exc {
-    public ParameterExpanderExc(String msg, Object[] objects) {
-      super(msg, objects);
+    public ParameterExpanderExc(String msg) {
+      super(msg);
     }
   }
 }
\ No newline at end of file
diff --git a/source/mir/util/ReflectionRoutines.java b/source/mir/util/ReflectionRoutines.java
new file mode 100755 (executable)
index 0000000..b15014f
--- /dev/null
@@ -0,0 +1,60 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.util;\r
+\r
+import org.apache.commons.beanutils.MethodUtils;\r
+\r
+import java.lang.reflect.InvocationTargetException;\r
+\r
+public class ReflectionRoutines {\r
+  private ReflectionRoutines() {\r
+  }\r
+\r
+  /**\r
+   * Method to overcome a shortcoming in {@link org.apache.commons.beanutils}'s\r
+   *     {@link MethodUtils#invokeMethod(Object, String, Object[])} involving\r
+   *     parameters that are <code>null</code> \r
+   */\r
+  public static Object invokeMethod(Object aTarget, String aMethodName, Object[] aParameters)\r
+      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {\r
+    Class parameterTypes[] = new Class[aParameters.length];\r
+\r
+    for (int i=0; i<aParameters.length; i++) {\r
+      if (aParameters[i] == null) {\r
+        parameterTypes[i] = Object.class;\r
+      }\r
+      else {\r
+        parameterTypes[i] = aParameters[i].getClass();\r
+      }\r
+    }\r
+\r
+    return MethodUtils.invokeMethod(aTarget, aMethodName, aParameters, parameterTypes);\r
+  }\r
+}\r
diff --git a/source/mir/util/ResourceBundleGeneratorFunction.java b/source/mir/util/ResourceBundleGeneratorFunction.java
deleted file mode 100755 (executable)
index c31b85e..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 The Mir-coders group
- *
- * This file is part of Mir.
- *
- * Mir is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Mir is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Mir; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
- * If you do not wish to do so, delete this exception statement from your version.
- */
-package mir.util;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Vector;
-
-import mir.generator.Generator;
-import mir.generator.GeneratorExc;
-
-import org.apache.struts.util.MessageResources;
-
-public class ResourceBundleGeneratorFunction implements Generator.GeneratorFunction {
-  private List messages;
-  private List locales;
-
-  public ResourceBundleGeneratorFunction(Locale aLocale, MessageResources aMessages) {
-    this(new Locale[] { aLocale}, new MessageResources[] {aMessages} );
-  }
-
-  public ResourceBundleGeneratorFunction(Locale[] aLocales, MessageResources[] aMessages) {
-    locales = new Vector();
-    messages = new Vector();
-
-    for(int i=0; i<aMessages.length; i++) {
-      messages.add(aMessages[i]);
-    }
-
-    for(int i=0; i<aLocales.length; i++) {
-      locales.add(aLocales[i]);
-    }
-  }
-
-  public Object perform(List aParameters) throws GeneratorExc {
-    List extraParameters = new Vector(aParameters);
-
-    if (aParameters.size()<1)
-      throw new GeneratorExc("ResourceBundleGeneratorFunction: at least 1 parameter expected");
-
-    if (!(aParameters.get(0) instanceof String))
-      throw new GeneratorExc("encodeHTMLGeneratorFunction: parameters must be strings");
-
-    String key = (String) aParameters.get(0);
-    extraParameters.remove(0);
-
-    String message=null;
-    Iterator j = locales.iterator();
-    while (j.hasNext() && (message == null || message.trim().length()==0)) {
-      Locale locale = (Locale) j.next();
-
-      Iterator i = messages.iterator();
-      while (i.hasNext() && (message == null || message.trim().length()==0)) {
-        message = ( (MessageResources) i.next()).getMessage(locale, key, extraParameters.toArray());
-      }
-    }
-
-    if (message == null) {
-      return new String("??" + key + "??");
-    }
-    else {
-      return message;
-    }
-  };
-}
\ No newline at end of file
diff --git a/source/mir/util/StreamCopier.java b/source/mir/util/StreamCopier.java
new file mode 100755 (executable)
index 0000000..b259b9a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.util;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+public class StreamCopier {
+  public static void copy(InputStream aSource, OutputStream aDestination) throws IOException {
+    byte buffer[] = new byte[16000];
+    int amountRead;
+
+    do {
+      amountRead = aSource.read(buffer);
+      if (amountRead>0)
+        aDestination.write(buffer, 0, amountRead);
+    }
+    while (amountRead>0);
+    aDestination.flush();
+  }
+}
index ee08f21..04bbc72 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 
@@ -32,6 +32,8 @@ package mir.util;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
 
 public class StringParseRoutines {
 
@@ -41,8 +43,9 @@ public class StringParseRoutines {
   private final static String VALUE = "[^;]*";
   private final static String SEMICOLON = ";";
 
-  //  a=sdfb; c=d; e=f
-
+  /**
+   * Parses an expression of the form " a = b ; c = d" into a map
+   */
   public static Map parseValueList(String anExpression) throws SimpleParser.SimpleParserFailure, SimpleParser.SimpleParserExc {
     String key;
     String value;
@@ -67,4 +70,58 @@ public class StringParseRoutines {
 
     return result;
   }
+
+  /**
+   * Utility function for {@link #parseBracketedExpression}:
+   * Adds a single part of a bracketed expression by looking for a
+   * terminator.
+   */
+  private static  int findNextBracketedPart(String anExpression, int aStartingPosition, char anEscape, String aTerminator, List aResult) {
+    int position = aStartingPosition;
+    StringBuffer result = new StringBuffer();
+
+    while (position<anExpression.length()) {
+      if (anExpression.charAt(position)==anEscape && position+1<anExpression.length()) {
+        result.append(anExpression.charAt(position+1));
+        position++;
+        position++;
+      }
+      else if (anExpression.startsWith(aTerminator, position)) {
+        aResult.add(result.toString());
+        return position;
+      }
+      else {
+        result.append(anExpression.charAt(position));
+        position++;
+      }
+    }
+
+    aResult.add(result.toString());
+    return -1;
+  }
+
+  /**
+   * Parses a "bracketed expression" into parts.
+   * "Bracketed" here means the expression consists of plain text and bracketed
+   * parts. e.g. <code>"some string {some expression} some string"</code>.
+   * { here starts a bracket, } ends one.
+   */
+  public static List parseBracketedExpression(String anExpression, char anEscape,
+      String anOpeningBracket, String aClosingBracket) {
+    List result = new ArrayList();
+    int position = 0;
+
+    do {
+      position = findNextBracketedPart(anExpression, position, anEscape, anOpeningBracket, result);
+      if (position>=0) {
+        position+=anOpeningBracket.length();
+        position = findNextBracketedPart(anExpression, position, anEscape, aClosingBracket, result);
+        if (position>0) {
+          position+=aClosingBracket.length();
+        }
+      }
+    } while (position>=0);
+
+    return result;
+  }
 }
\ No newline at end of file
index 0627dbc..a7a41b6 100755 (executable)
@@ -32,7 +32,7 @@ package mir.util;
 import gnu.regexp.RE;
 
 import java.util.List;
-import java.util.Vector;
+import java.util.ArrayList;
 
 public class StringRoutines {
 
@@ -86,12 +86,6 @@ public class StringRoutines {
     return result.toString();
   }
   /**
-   *
-   * @param aText
-   * @param anEscapeCharacater
-   * @param aCharactersToReplace
-   * @param aStringsToSubstitute
-   * @return
    */
 
   public static String replaceEscapedStringCharacters(String aText, char anEscapeCharacter, char[] aCharactersToReplace, String[] aStringsToSubstitute) {
@@ -139,7 +133,7 @@ public class StringRoutines {
       return (String) aValue;
 
     if (aValue instanceof Integer)
-      return ((Integer) aValue).toString();
+      return aValue.toString();
 
     if (aValue == null)
       return "";
@@ -162,16 +156,7 @@ public class StringRoutines {
     throw new Exception("Integer expected, "+aValue+" found");
   }
 
-  /**
-   *
-   * @param aSource
-   * @param aSearchExpression
-   * @param aReplacement
-   * @return
-   * @throws Exception
-   */
-  public static String performRegularExpressionReplacement(String aSource,
-      String aSearchExpression, String aReplacement) throws UtilExc {
+  public static String performRegularExpressionReplacement(String aSource, String aSearchExpression, String aReplacement) {
     try {
       RE regularExpression;
 
@@ -184,8 +169,7 @@ public class StringRoutines {
     }
   }
 
-  public static String performCaseInsensitiveRegularExpressionReplacement(String aSource,
-      String aSearchExpression, String aReplacement) throws UtilExc {
+  public static String performCaseInsensitiveRegularExpressionReplacement(String aSource, String aSearchExpression, String aReplacement) {
     try {
       RE regularExpression;
 
@@ -198,15 +182,7 @@ public class StringRoutines {
     }
   }
 
-  /**
-   *
-   * @param aSource
-   * @param aSearchExpression
-   * @return
-   * @throws REException
-   */
-  public static boolean performRegularExpressionSearch(String aSource,
-      String aSearchExpression) throws UtilExc {
+  public static boolean performRegularExpressionSearch(String aSource, String aSearchExpression) {
     try {
       RE regularExpression;
 
@@ -230,10 +206,9 @@ public class StringRoutines {
    */
 
   public static List splitString(String aString, String aSeparator) {
-    List result= new Vector();
+    List result= new ArrayList();
     int previousPosition = 0;
     int position;
-    int endOfNamePosition;
 
     if (aString!=null) {
       while ( (position = aString.indexOf(aSeparator, previousPosition)) >= 0) {
@@ -263,7 +238,7 @@ public class StringRoutines {
    * @return
    */
   public static List separateString(String aString, String aSeparator) {
-    List result= new Vector();
+    List result= new ArrayList();
     int previousPosition = 0;
     int position;
 
@@ -288,13 +263,13 @@ public class StringRoutines {
    */
 
   public static List splitStringWithEscape(String aString, char aSeparator, char anEscape) {
-    List result= new Vector();
+    List result= new ArrayList();
     int previousPosition = 0;
     int position;
-    int endOfNamePosition;
+
     StringBuffer currentItem = new StringBuffer();
 
-    if (aString!=null) {
+    if (aString!=null && aString.length()>0) {
       while ((position = indexOfCharacters(aString, new char[] {aSeparator, anEscape}, previousPosition))>=0) {
         currentItem.append(aString.substring(previousPosition, position));
 
@@ -303,11 +278,13 @@ public class StringRoutines {
           currentItem.delete(0, currentItem.length());
         }
         else {
-          currentItem.append(aString.charAt(position));
           if (aString.length()>position+1) {
             position=position+1;
             currentItem.append(aString.charAt(position));
           }
+          else {
+            currentItem.append(aString.charAt(position));
+          }
         }
         previousPosition = position + 1;
       }
index ff32bc3..412ecad 100755 (executable)
@@ -37,7 +37,6 @@ import java.util.Vector;
 
 
 /**
- *
  * <p>Title: </p>
  * <p>Description:
  *   Class to parse structured content:
@@ -58,10 +57,6 @@ import java.util.Vector;
  *  <p>
  *    Parsing is be very optimistic: no exception is ever to be thrown.
  *  </p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: </p>
- * @author not attributable
- * @version 1.0
  */
 public class StructuredContentParser {
   public StructuredContentParser() {
@@ -133,7 +128,7 @@ public class StructuredContentParser {
 
     public char scan() {
       if (!isAtEnd()) {
-        char result =data.charAt(position);
+        char result = data.charAt(position);
         position++;
         return result;
       }
@@ -196,9 +191,7 @@ public class StructuredContentParser {
   }
 
   public static Object parseObject(Scanner aScanner) {
-    Object result = null;
-
-    aScanner.skipSpace();
+   aScanner.skipSpace();
 
     if (!aScanner.isAtEnd()) {
       char data = aScanner.peek();
diff --git a/source/mir/util/generator/BundleGeneratorFunction.java b/source/mir/util/generator/BundleGeneratorFunction.java
new file mode 100755 (executable)
index 0000000..a33a5ed
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.util.generator;
+
+import mir.bundle.Bundle;
+import mir.generator.Generator;
+import mir.generator.GeneratorExc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class BundleGeneratorFunction implements Generator.Function {
+  private Bundle bundles[];
+
+  public BundleGeneratorFunction(Bundle aBundles[]) {
+    bundles = aBundles;
+  }
+
+  public Object perform(List aParameters) throws GeneratorExc {
+    List extraParameters = new ArrayList(aParameters);
+
+    if (aParameters.size()<1)
+      throw new GeneratorExc("ResourceBundleGeneratorFunction: at least 1 parameter expected");
+
+    String key = (String) aParameters.get(0);
+    extraParameters.remove(0);
+
+    String message=null;
+    for (int j=0; j<bundles.length; j++) {
+      message= bundles[j].getValue(key, extraParameters);
+      if (message!=null)
+        break;
+    }
+
+    if (message == null) {
+      return new String("[" + key + "]");
+    }
+    else {
+      return message;
+    }
+  }
+}
\ No newline at end of file
diff --git a/source/mir/util/generator/ReflectionGeneratorFunctionAdapter.java b/source/mir/util/generator/ReflectionGeneratorFunctionAdapter.java
new file mode 100755 (executable)
index 0000000..1e98f7c
--- /dev/null
@@ -0,0 +1,75 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.util.generator;\r
+\r
+import mir.generator.Generator;\r
+import mir.generator.GeneratorExc;\r
+import mir.generator.GeneratorFailure;\r
+import mir.util.ReflectionRoutines;\r
+\r
+import java.util.List;\r
+import java.lang.reflect.InvocationTargetException;\r
+\r
+import org.apache.commons.beanutils.MethodUtils;\r
+\r
+/**\r
+ * Class to adapt methods with some name to a\r
+ * {@link Generator.Function}\r
+ */\r
+\r
+public class ReflectionGeneratorFunctionAdapter implements Generator.Function {\r
+  private Object target;\r
+  private String methodName;\r
+\r
+  public ReflectionGeneratorFunctionAdapter(Object aTarget, String aMethodName) {\r
+    target = aTarget;\r
+    methodName = aMethodName;\r
+  }\r
+\r
+  /** {@inheritDoc} */\r
+  public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {\r
+    try {\r
+      return ReflectionRoutines.invokeMethod(target, methodName, aParameters.toArray());\r
+    }\r
+    catch (InvocationTargetException t) {\r
+      if (t.getTargetException() instanceof GeneratorExc) {\r
+        throw (GeneratorExc) t.getTargetException();\r
+      }\r
+\r
+      throw new GeneratorFailure(t.getTargetException());\r
+    }\r
+    catch (IllegalAccessException t) {\r
+      throw new GeneratorFailure(t);\r
+    }\r
+    catch (NoSuchMethodException t) {\r
+      throw new GeneratorFailure(t);\r
+    }\r
+  }\r
+}\r
diff --git a/source/mir/util/generator/ReflectionGeneratorFunctionsAdapter.java b/source/mir/util/generator/ReflectionGeneratorFunctionsAdapter.java
new file mode 100755 (executable)
index 0000000..3ac9bb7
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mir.util.generator;\r
+\r
+import mir.generator.Generator;\r
+\r
+/**\r
+ * Helper class to expose methods from an ordinary object as\r
+ * {@link Generator.Function}s;\r
+ */\r
+public class ReflectionGeneratorFunctionsAdapter {\r
+  private Object object;\r
+\r
+  public ReflectionGeneratorFunctionsAdapter(Object anObject) {\r
+    object = anObject;\r
+  }\r
+\r
+  /**\r
+   * Returns a {@link Generator.Function} for <code>aName</code>\r
+   * by adapting methods by the same name from the wrapped\r
+   * <code>object</code>.\r
+   */\r
+  public Generator.Function get(String aName) {\r
+    return new ReflectionGeneratorFunctionAdapter(object, aName);\r
+  }\r
+}\r
index 5a9c094..ee70a13 100755 (executable)
@@ -35,6 +35,9 @@ import java.io.FileInputStream;
 import java.io.InputStream;
 import java.io.StringReader;
 import java.io.File;
+import java.io.Reader;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -97,23 +100,32 @@ public class XMLParserEngine {
   }
 
   /**
-   *
-   * @param anInputStream
-   * @param aRootHandler
-   * @throws mir.util.xml.XMLParserFailure
-   * @throws mir.util.xml.XMLParserExc
+   * Parse xml coming from an input stream with the system default encoding
    */
   public void parse(String aProvider, InputStream anInputStream, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
-    parse(aProvider, new java.io.InputStreamReader(anInputStream), aRootHandler);
+    parse(aProvider, new InputStreamReader(anInputStream), aRootHandler);
+  }
+
+  /**
+   * Parse xml coming from an input stream according to the given encoding
+   */
+  public void parse(String aProvider, InputStream anInputStream, String anEncoding, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
+    try {
+      parse(aProvider, new InputStreamReader(anInputStream, anEncoding), aRootHandler);
+    }
+    catch (UnsupportedEncodingException e) {
+      throw new XMLParserExc("Unsupported encoding: " + anEncoding);
+    }
   }
 
+
   /**
    *
    * @param aRootHandler
    * @throws mir.util.xml.XMLParserFailure
    * @throws mir.util.xml.XMLParserExc
    */
-  public void parse(String aProvider, java.io.Reader aReader, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
+  public void parse(String aProvider, Reader aReader, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
     XMLParserProvider provider = (XMLParserProvider) providers.get(aProvider);
 
     if (provider==null)
@@ -170,7 +182,7 @@ public class XMLParserEngine {
   }
 
   public interface XMLParserProvider {
-    public void parse(java.io.Reader aReader, XMLParserReceiver aReceiver) throws XMLParserExc, XMLParserFailure;
+    public void parse(Reader aReader, XMLParserReceiver aReceiver) throws XMLParserExc, XMLParserFailure;
   }
 
   private class XMLParserRunner implements XMLParserReceiver {
index f9bbc52..fb4859d 100755 (executable)
@@ -155,6 +155,7 @@ public class XMLReaderTool {
     return result;
   }
 
+  /** formats an XML name as it would look in an XML file */
   public static String normalizeXMLName(mir.util.xml.XMLName aName) {
     String result = aName.getLocalName();
     if (aName.getPrefix().length() > 0)
index 567e0fc..0e8a851 100755 (executable)
@@ -5,6 +5,7 @@ import java.util.*;
 import org.xml.sax.InputSource;\r
 import org.xml.sax.SAXException;\r
 import org.xml.sax.Locator;\r
+import org.xml.sax.SAXParseException;\r
 import mir.util.ExceptionFunctions;\r
 \r
 /**\r
@@ -44,6 +45,10 @@ class XMLSAXParserProvider implements XMLParserEngine.XMLParserProvider {
         throw (XMLParserFailure) t;\r
       }\r
 \r
+      if (t instanceof SAXParseException) {\r
+        throw new XMLParserExc(t.getMessage());\r
+      }\r
+\r
       throw new XMLParserFailure(t);\r
     }\r
     catch (Throwable t) {\r
index e956ae1..1c6ff42 100755 (executable)
@@ -67,6 +67,20 @@ public class HTMLScanner {
         (aCharacter == ':');
   }
 
+  private boolean isValidUnQuotedAttributeCharacter(char aCharacter) {
+    int type = Character.getType(aCharacter);
+
+    return
+        (type == Character.UPPERCASE_LETTER)  ||
+        (type == Character.LOWERCASE_LETTER)  ||
+        (type == Character.DECIMAL_DIGIT_NUMBER)  ||
+        (aCharacter == '.') ||
+        (aCharacter == '#') ||
+        (aCharacter == '-') ||
+        (aCharacter == '_') ||
+        (aCharacter == ':');
+  }
+
   private void skipWhiteSpace() throws IOException {
     while (!reader.isAtEnd() && Character.isWhitespace(reader.peek())) {
       reader.get();
@@ -122,7 +136,7 @@ public class HTMLScanner {
           reader.get();
       }
       else {
-        while (!reader.isAtEnd() && isValidTagNameCharacter(reader.peek())) {
+        while (!reader.isAtEnd() && isValidUnQuotedAttributeCharacter(reader.peek())) {
           result.append(reader.get());
         }
       }
@@ -183,7 +197,11 @@ public class HTMLScanner {
             reader.get();
             if (!reader.isAtEnd() && reader.peek()=='-') {
               reader.get();
-              break;
+              if (!reader.isAtEnd() && reader.peek()=='>') {
+                reader.get();
+                break;
+              }
+              result.append('-');
             }
             result.append('-');
           }
index 68d2127..5856214 100755 (executable)
@@ -38,7 +38,8 @@ public class HTMLSchemaInformation {
     addInlineTag("dt");
     addInlineTag("em");
     addInlineTag("fieldset");
-    addInlineTag("font");
+    // Zapata: Removed because of frequent abuse by html writers
+    // addInlineTag("font");
     addBlockTag("form");
     addBodylessTag("frame");
     addInlineTag("frameset");
index 42cece2..f64a208 100755 (executable)
 
 package mircoders.accesscontrol;
 
-import java.util.List;
-import java.util.Vector;
-
 import mir.config.MirPropertiesConfiguration;
 import mir.log.LoggerWrapper;
 import mircoders.entity.EntityUsers;
-import mircoders.module.*;
-import mircoders.storage.*;
+import mircoders.module.ModuleContent;
+
+import java.util.List;
+import java.util.Vector;
 
 public class AccessControl {
   private UserAccessControl user;
@@ -187,7 +186,7 @@ public class AccessControl {
     private boolean lockingOptional;
 
     public ArticleAccessControl(boolean aLockingEnabled, boolean aLockingOptional) {
-      contentModule = new ModuleContent(DatabaseContent.getInstance());
+      contentModule = new ModuleContent();
       lockingEnabled = aLockingEnabled;
       lockingOptional = aLockingOptional;
     }
index b87ae15..144eddc 100755 (executable)
@@ -45,7 +45,7 @@ import mircoders.storage.DatabaseContentToMedia;
  * this class implements mapping of one line of the database table content
  * to a java object
  *
- * @version $Id: EntityContent.java,v 1.19.2.6 2004/02/08 21:05:02 zapata Exp $
+ * @version $Id: EntityContent.java,v 1.19.2.7 2004/11/21 22:07:13 zapata Exp $
  * @author mir-coders group
  *
  */
@@ -78,7 +78,7 @@ public class EntityContent extends AbstractEntity {
     Connection con=null;Statement stmt=null;
     String sql = "update content set is_produced='" + value + "' where id='" + getId()+"'";
     try {
-      con = storageObject.getPooledCon();
+      con = storageObject.obtainConnection();
       /** todo should be preparedStatement: faster!! */
       stmt = con.createStatement();
       storageObject.executeUpdate(stmt,sql);
index 82be8d5..1cff969 100755 (executable)
 
 package mircoders.entity;
 
-import java.io.File;
-import java.io.IOException;
+import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.Statement;
 
-import mir.config.MirPropertiesConfiguration;
 import mir.log.LoggerWrapper;
-import mir.misc.FileUtil;
 import mir.storage.StorageObject;
 import mir.storage.StorageObjectFailure;
+import mir.util.StreamCopier;
 import mircoders.media.ImageProcessor;
 
-import org.postgresql.largeobject.BlobInputStream;
-import org.postgresql.largeobject.LargeObject;
-import org.postgresql.largeobject.LargeObjectManager;
-
 /**
  *
  * @author RK, mh, mir-coders
- * @version $Id: EntityImages.java,v 1.21.2.4 2004/01/18 17:30:58 zapata Exp $
+ * @version $Id: EntityImages.java,v 1.21.2.5 2004/11/21 22:07:13 zapata Exp $
  */
 
 
@@ -77,134 +67,52 @@ public class EntityImages extends EntityUploadedMedia
     setStorage(theStorage);
   }
 
-  //
-  // methods
-
-
+  /**
+   * Retrieves the image data
+   */
   public InputStream getImage() throws StorageObjectFailure {
-    logger.debug("EntityImages.getimage started");
-    java.sql.Connection con=null;
-    Statement stmt=null;
-    BlobInputStream in;
-    InputStream img_in = null;
-
     try {
-      con = storageObject.getPooledCon();
-      con.setAutoCommit(false);
-      LargeObjectManager lom;
-      java.sql.Connection jCon;
-      stmt = con.createStatement();
-      ResultSet rs = storageObject.executeSql(stmt,
-          "select image_data from images where id="+getId());
-      jCon = ((com.codestudio.sql.PoolManConnectionHandle)con)
-           .getNativeConnection();
-      lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI();
-      if(rs!=null) {
-        if (rs.next()) {
-          LargeObject lob = lom.open(rs.getInt(1));
-          in = (BlobInputStream)lob.getInputStream();
-          img_in = new ImageInputStream(in, con, stmt);
-        }
-        rs.close();
-      }
+      return storageObject.getBinaryField("select image_data from images where id="+getId());
     }
-    catch (Throwable t) {
-      logger.error("EntityImages.getImage failed: " + t.toString());
-      t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
-
-      try {
-        con.setAutoCommit(true);
-      }
-      catch (Throwable e) {
-        logger.error("EntityImages.getImage resetting transaction mode failed: " + e.toString());
-        e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
-      }
-
-      try {
-        storageObject.freeConnection(con, stmt);
-      }
-      catch (Throwable e) {
-        logger.error("EntityImages.getImage freeing connection failed: " +e.toString());
-      }
-
-      throw new StorageObjectFailure(t);
+    catch (SQLException e) {
+      throw new StorageObjectFailure(e);
     }
-
-    return img_in;
   }
 
-  public void setImage(InputStream in, String type) throws StorageObjectFailure {
-    // todo: failures should be treated in a better way: exception -> rollback instead
+  /**
+   * Processes and saves image data
+   */
+  public void setImage(InputStream anInputStream, String type) throws StorageObjectFailure {
+    // todo: failures should be treated anInputStream a better way: exception -> rollback instead
     //  of commit
-    if (in != null) {
-
-      Connection con = null;
-      PreparedStatement pstmt = null;
-      File f = null;
+    if (anInputStream != null) {
       try {
-        logger.debug("EntityImages.settimage :: making internal representation of image");
+        ByteArrayOutputStream inputData = new ByteArrayOutputStream();
+        StreamCopier.copy(anInputStream, inputData);
 
-        f = File.createTempFile("mir", ".tmp",
-                new File(MirPropertiesConfiguration.instance().getString("TempDir")));
-        FileUtil.write(f, in);
-        ImageProcessor processor = new ImageProcessor(f);
-
-        con = storageObject.getPooledCon();
-        con.setAutoCommit(false);
-        LargeObjectManager lom;
-        java.sql.Connection connection;
-        connection = ((com.codestudio.sql.PoolManConnectionHandle)con).getNativeConnection();
+        ImageProcessor processor = new ImageProcessor(inputData.toByteArray());
+        processor.descaleImage(maxImageSize, minDescaleRatio, minDescaleReduction);
 
-        lom = ((org.postgresql.Connection) connection).getLargeObjectAPI();
+        ByteArrayOutputStream imageData = new ByteArrayOutputStream();
+        processor.writeScaledData(imageData, type);
+        storageObject.setBinaryField("update images set image_data = ? where id = "+getId(), imageData.toByteArray());
 
-        int oidImage = lom.create();
-        LargeObject lobImage = lom.open(oidImage);
-        processor.descaleImage(maxImageSize, minDescaleRatio, minDescaleReduction);
-        processor.writeScaledData(lobImage.getOutputStream(), type);
-        lobImage.close();
         setFieldValue("img_height", new Integer(processor.getScaledHeight()).toString());
         setFieldValue("img_width", new Integer(processor.getScaledWidth()).toString());
 
-        int oidIcon = lom.create();
-        LargeObject lobIcon = lom.open(oidIcon);
+        imageData.reset();
         processor.descaleImage(maxIconSize, minDescaleRatio, minDescaleReduction);
-        processor.writeScaledData(lobIcon.getOutputStream(), type);
-        lobIcon.close();
+        processor.writeScaledData(imageData, type);
+        storageObject.setBinaryField("update images set icon_data = ? where id = "+getId(), imageData.toByteArray());
 
         setFieldValue("icon_height", new Integer(processor.getScaledHeight()).toString());
         setFieldValue("icon_width", new Integer(processor.getScaledWidth()).toString());
 
-        setFieldValue("image_data", new Integer(oidImage).toString());
-        setFieldValue("icon_data", new Integer(oidIcon).toString());
         update();
       }
       catch (Exception e) {
         throw new StorageObjectFailure(e);
       }
-      finally {
-        try {
-          if (con!=null)
-            con.setAutoCommit(true);
-          // get rid of the temp. file
-        }
-        catch (Throwable e) {
-          logger.error("EntityImages.setImage: unable to reset the connection to auto-commit:" + e.toString());
-        }
-        try {
-          f.delete();
-        }
-        catch (Throwable t) {
-          logger.error("EntityImages.setImage: unable to delete the temporary file:" + t.toString());
-        }
-
-        try {
-          if (con!=null)
-            storageObject.freeConnection(con,pstmt);
-        }
-        catch (Throwable t) {
-          logger.error("EntityImages.setImage: unable to free the connection:" + t.toString());
-        }
-      }
     }
   }
 
@@ -215,85 +123,11 @@ public class EntityImages extends EntityUploadedMedia
    * It will also take care of closing the OutputStream.
    */
   public InputStream getIcon() throws StorageObjectFailure {
-    Connection con=null;
-    Statement stmt=null;
-    BlobInputStream in=null;
-    ImageInputStream img_in=null;
-
     try {
-      con = storageObject.getPooledCon();
-      con.setAutoCommit(false);
-      LargeObjectManager lom;
-      java.sql.Connection jCon;
-      stmt = con.createStatement();
-      ResultSet rs = storageObject.executeSql(stmt, "select icon_data from images where id="+getId());
-      jCon = ((com.codestudio.sql.PoolManConnectionHandle)con)
-           .getNativeConnection();
-      lom = ((org.postgresql.Connection)jCon).getLargeObjectAPI();
-      if(rs!=null) {
-        if (rs.next()) {
-          LargeObject lob = lom.open(rs.getInt(1));
-          in = (BlobInputStream)lob.getInputStream();
-          img_in = new ImageInputStream( in, con ,stmt);
-          //img_data = rs.getBytes(1);
-        }
-        rs.close();
-      }
+      return storageObject.getBinaryField("select icon_data from images where id="+getId());
     }
-    catch (Throwable t) {
-      logger.error("EntityImages.getIcon failed: "+t.toString());
-      t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
-
-      try {
-        con.setAutoCommit(true);
-      }
-      catch (SQLException e) {
-        logger.error("EntityImages.getIcon resetting transaction mode failed: " + e.toString());
-        e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
-      }
-      try {
-        storageObject.freeConnection(con, stmt);
-      }
-      catch (Throwable e) {
-       logger.error("EntityImages -- freeing connection failed: " + e.getMessage());
-      }
-
-      throw new StorageObjectFailure(t);
-    }
-
-    return img_in;
-  }
-
-  /**
-   * a small wrapper class that allows us to store the DB connection resources
-   * that the BlobInputStream is using and free them upon closing of the stream
-   */
-  private class ImageInputStream extends InputStream {
-
-    InputStream _in;
-    Connection _con;
-    Statement _stmt;
-
-    public ImageInputStream(BlobInputStream in, Connection con,
-                            Statement stmt ) {
-      _in = in;
-      _con = con;
-      _stmt = stmt;
-    }
-
-    public void close () throws IOException {
-      _in.close();
-      try {
-        _con.setAutoCommit(true);
-        storageObject.freeConnection(_con,_stmt);
-      }
-      catch (Exception e) {
-        throw new IOException("close(): "+e.toString());
-      }
-    }
-
-    public int read() throws IOException {
-      return _in.read();
+    catch (SQLException e) {
+      throw new StorageObjectFailure(e);
     }
   }
 }
index 8d7c9f7..110f694 100755 (executable)
@@ -42,7 +42,7 @@ import mircoders.storage.DatabaseUploadedMedia;
 /**
  *
  * @author mh, mir-coders group
- * @version $Id: EntityUploadedMedia.java,v 1.26.2.7 2004/02/08 21:05:02 zapata Exp $
+ * @version $Id: EntityUploadedMedia.java,v 1.26.2.8 2004/11/21 22:07:13 zapata Exp $
  */
 
 public class EntityUploadedMedia extends AbstractEntity {
@@ -62,8 +62,23 @@ public class EntityUploadedMedia extends AbstractEntity {
     super.update();
 
     try {
-      storageObject.executeUpdate( "update content set is_produced='0' where exists(select * from content_x_media where content_id=content.id and media_id=" + getId()+")");
-      storageObject.executeUpdate( "update content set is_produced='0' where exists(select * from comment_x_media, comment where comment_x_media.comment_id=comment.id and comment.to_media=content.id and comment_x_media.media_id=" + getId()+")");
+      storageObject.executeUpdate(
+          "update content " +
+          "set is_produced='0' " +
+          "from content_x_media cxm " +
+          "where" +
+          "   cxm.content_id=content.id and cxm.media_id=" + getId()
+      );
+
+      storageObject.executeUpdate(
+          "update content " +
+          "set is_produced='0' " +
+          "from comment_x_media cxm, comment c "+
+          "where " +
+          "   cxm.comment_id = c.id and " +
+          "   c.to_media=content.id and " +
+          "   cxm.media_id=" + getId()
+      );
     }
     catch (SQLException e) {
       throw new StorageObjectFailure(e);
index 184142f..0009749 100755 (executable)
@@ -77,7 +77,7 @@ public class Abuse {
   private String articleBlockAction;
   private String commentBlockAction;
   private List log;
-  private String configFile = MirGlobal.config().getStringWithHome("Abuse.Config");
+  private File configFile = MirGlobal.config().getFile("Abuse.Config");
 
   private MirPropertiesConfiguration configuration;
 
@@ -373,7 +373,7 @@ public class Abuse {
         ExtendedProperties configuration = new ExtendedProperties();
 
         try {
-          configuration = new ExtendedProperties(configFile);
+          configuration = new ExtendedProperties(configFile.getAbsolutePath());
         }
         catch (FileNotFoundException e) {
         }
@@ -409,7 +409,7 @@ public class Abuse {
         configuration.addProperty("abuse.articleBlockAction", getArticleBlockAction());
         configuration.addProperty("abuse.commentBlockAction", getCommentBlockAction());
 
-        configuration.save(new BufferedOutputStream(new FileOutputStream(new File(configFile)),8192), "Anti abuse configuration");
+        configuration.save(new BufferedOutputStream(new FileOutputStream(configFile),8192), "Anti abuse configuration");
       }
       catch (Throwable t) {
         throw new RuntimeException(t.toString());
@@ -762,10 +762,16 @@ public class Abuse {
     }
   }
 
+  private String escapeConfigListEntry(String aFilterPart) {
+    return StringRoutines.replaceStringCharacters(aFilterPart,
+        new char[] {'\\', ':'},
+        new String[] {"\\\\", "\\:"});
+  }
+
   private String escapeFilterPart(String aFilterPart) {
     return StringRoutines.replaceStringCharacters(aFilterPart,
-        new char[] {'\\', ':', '\n', '\r', '\t', ' '},
-        new String[] {"\\\\", "\\:", "\\n", "\\r", "\\t", "\\ "});
+        new char[] {'\\', '\n', '\r', '\t', ' '},
+        new String[] {"\\\\", "\\n", "\\r", "\\t", "\\ "});
   }
 
   private String deescapeFilterPart(String aFilterPart) {
@@ -783,11 +789,11 @@ public class Abuse {
         FilterRule filter = (FilterRule) i.next();
 
         String filterconfig =
-            escapeFilterPart(filter.getType()) + ":" +
-            escapeFilterPart(filter.getExpression()) + ":" +
-            escapeFilterPart(filter.getArticleAction()) + ":" +
-            escapeFilterPart(filter.getCommentAction()) + ":" +
-            escapeFilterPart(filter.getComments()) + ":";
+            escapeConfigListEntry(escapeFilterPart(filter.getType())) + ":" +
+            escapeConfigListEntry(escapeFilterPart(filter.getExpression())) + ":" +
+            escapeConfigListEntry(escapeFilterPart(filter.getArticleAction())) + ":" +
+            escapeConfigListEntry(escapeFilterPart(filter.getCommentAction())) + ":" +
+            escapeConfigListEntry(escapeFilterPart(filter.getComments())) + ":";
 
         if (filter.getLastHit() != null)
           filterconfig = filterconfig + filter.getLastHit().getTime();
diff --git a/source/mircoders/global/DatabaseEngine.java b/source/mircoders/global/DatabaseEngine.java
new file mode 100755 (executable)
index 0000000..32dd644
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mircoders.global;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.util.Properties;
+
+import mir.config.MirPropertiesConfiguration;
+import org.apache.commons.dbcp.ConnectionFactory;
+import org.apache.commons.dbcp.DriverConnectionFactory;
+import org.apache.commons.dbcp.PoolableConnection;
+import org.apache.commons.dbcp.PoolableConnectionFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPool;
+
+public class DatabaseEngine {
+  private ObjectPool connectionPool;
+
+  public DatabaseEngine() {
+    MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
+
+    Properties connectionProperties = new Properties();
+    connectionProperties.put("user", configuration.getString("Database.Username"));
+    connectionProperties.put("password", configuration.getString("Database.Password"));
+    String dbHost = configuration.getString("Database.Host");
+    String dbPort = configuration.getString("Database.Port");
+    String dbName = configuration.getString("Database.Name");
+    String dbUrl = "jdbc:postgresql://"+dbHost+":"+dbPort+"/"+dbName+"?compatible=7.1";
+    String dbDriver = configuration.getString("Database.Driver");
+    Driver driver;
+    try {
+      driver = (Driver) (Class.forName(dbDriver)).newInstance();
+    }
+    catch (ClassNotFoundException e) {
+      throw new Error("JDBC Driver not found: " + e.toString());
+    }
+    catch (InstantiationException e) {
+      throw new Error("Can't instantiate JDBC Driver: " + e.toString());
+    }
+    catch (IllegalAccessException e) {
+      throw new Error("No access to JDBC Driver: " + e.toString());
+    }
+
+    connectionPool = new GenericObjectPool(null);
+    ConnectionFactory rawConnectionFactory =
+        new DriverConnectionFactory(driver, dbUrl, connectionProperties);
+    new PoolableConnectionFactory(rawConnectionFactory, connectionPool,
+        null, "select now()", false, true);
+
+    // test the connection right before someone borrows it
+    ((GenericObjectPool) connectionPool).setTestOnBorrow(true);
+
+
+  }
+
+  /**
+   * Obtain a database connection
+   */
+  public Connection obtainConnection() throws Exception {
+    return (Connection) connectionPool.borrowObject();
+  }
+
+  /**
+   * release a previously obtained database connection
+   */
+  public void releaseConnection(Connection aConnection) throws Exception {
+    connectionPool.returnObject(aConnection);
+  }
+
+  /**
+   * Returns the native connection of a previously obtained connection
+   */
+  public Connection getNativeConnection(Connection aConnection) {
+    return ((PoolableConnection) aConnection).getDelegate();
+  }
+
+  public String getStatus() {
+    return
+        connectionPool.getNumActive() + " / " +
+        (connectionPool.getNumIdle()+connectionPool.getNumActive()) +
+        " db conn.";
+  }
+}
index bdd6921..f3722eb 100755 (executable)
@@ -48,12 +48,7 @@ public class MRUCache {
 
   public MRUCache() {
     logger = new LoggerWrapper("Global.MRUCache");
-    try {
-      configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (PropertiesConfigExc e) {
-      throw new RuntimeException("Can't get configuration: " + e.getMessage());
-    }
+    configuration = MirPropertiesConfiguration.instance();
     cacheMaxItems=Integer.parseInt(configuration.getString("Global.Cache.Items"));
     cache = new HashMap();
     mruList= new LinkedList();
index 4d328f8..2306d96 100755 (executable)
@@ -36,9 +36,13 @@ import java.util.List;
 import java.util.Map;\r
 import java.util.Vector;\r
 \r
+import mir.bundle.BasicBundleFactory;\r
+import mir.bundle.BundleFactory;\r
+import mir.bundle.CascadingBundleFactory;\r
+import mir.bundle.PropertiesFileBundleLoader;\r
 import mir.config.MirPropertiesConfiguration;\r
-import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;\r
 import mir.entity.adapter.EntityAdapter;\r
+import mir.log.LoggerEngine;\r
 import mir.log.LoggerWrapper;\r
 import mir.misc.ConfigException;\r
 import mircoders.accesscontrol.AccessControl;\r
@@ -61,6 +65,14 @@ public class MirGlobal {
   static private Map loggedInUserIds = new HashMap();\r
   static private LoggerWrapper logger = new LoggerWrapper("Global");\r
   static private LoggerWrapper adminUsageLogger = new LoggerWrapper("AdminUsage");\r
+//  static private ChangeEngine changeEngine = new ChangeEngine();\r
+  static private DatabaseEngine databaseEngine;\r
+\r
+  static private BundleFactory bundleFactory =\r
+      new CascadingBundleFactory(\r
+        new BasicBundleFactory(\r
+            new PropertiesFileBundleLoader(\r
+                config().getHome())));\r
 \r
   public synchronized static MirLocalizer localizer() {\r
     String localizerClassName;\r
@@ -73,17 +85,20 @@ public class MirGlobal {
         localizerClass = Class.forName(localizerClassName);\r
       }\r
       catch (Throwable t) {\r
-        throw new ConfigException("localizer class '" + localizerClassName + "' not found: " + t.toString());\r
+        throw new ConfigException("localizer class '" +\r
+            localizerClassName + "' not found: " + t.toString());\r
       }\r
 \r
       if (!(MirLocalizer.class.isAssignableFrom(localizerClass)))\r
-        throw new ConfigException("localizer class '" + localizerClassName + "' is not assignable from MirLocalizer");\r
+        throw new ConfigException("localizer class '" +\r
+            localizerClassName + "' is not assignable from MirLocalizer");\r
 \r
       try {\r
         localizer = new MirCachingLocalizerDecorator((MirLocalizer) localizerClass.newInstance());\r
       }\r
       catch (Throwable t) {\r
-        throw new ConfigException("localizer class '" + localizerClassName + "' cannot be instantiated: " + t.toString());\r
+        throw new ConfigException("localizer class '" +\r
+            localizerClassName + "' cannot be instantiated: " + t.toString());\r
       }\r
     }\r
 \r
@@ -98,7 +113,8 @@ public class MirGlobal {
 \r
     result.append((Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/(1024*1024));\r
     result.append("M in use, ");\r
-    result.append(Thread.currentThread().activeCount()).append(" active threads");\r
+    result.append(Thread.currentThread().activeCount()).append(" threads, ");\r
+    result.append(getDatabaseEngine().getStatus());\r
 \r
     return result.toString();\r
   }\r
@@ -110,16 +126,25 @@ public class MirGlobal {
     return abuse;\r
   }\r
 \r
+  /**\r
+   * returns the global change engine (used to track changed files)\r
+   */\r
+//  public static ChangeEngine getChangeEngine() {\r
+//    return changeEngine;\r
+//  }\r
+\r
   public static MirPropertiesConfiguration config() {\r
-    try {\r
-      return MirPropertiesConfiguration.instance();\r
-    }\r
-    catch (PropertiesConfigExc e) {\r
-      throw new RuntimeException(e.getMessage());\r
-    }\r
+    return MirPropertiesConfiguration.instance();\r
   }\r
 \r
-  public static ProducerEngine producerEngine() {\r
+  public synchronized static DatabaseEngine getDatabaseEngine() {\r
+    if (databaseEngine==null)\r
+      databaseEngine = new DatabaseEngine();\r
+\r
+    return databaseEngine;\r
+  }\r
+\r
+  public static ProducerEngine getProducerEngine() {\r
     if (producerEngine == null) {\r
       producerEngine = new ProducerEngine();\r
     }\r
@@ -182,13 +207,15 @@ public class MirGlobal {
     }\r
   }\r
 \r
-  private synchronized static MirAdminInterfaceLocalizer.MirSimpleEntityOperation getArticleOperationForName(String aName) {\r
+  private synchronized static MirAdminInterfaceLocalizer.MirSimpleEntityOperation\r
+      getArticleOperationForName(String aName) {\r
     try {\r
       if (articleOperations == null) {\r
         articleOperations = new HashMap();\r
         Iterator i = localizer().adminInterface().simpleArticleOperations().iterator();\r
         while (i.hasNext()) {\r
-          MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation = (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();\r
+          MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =\r
+              (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();\r
           articleOperations.put(operation.getName(), operation);\r
         }\r
       }\r
@@ -200,13 +227,15 @@ public class MirGlobal {
     }\r
   }\r
 \r
-  private synchronized static MirAdminInterfaceLocalizer.MirSimpleEntityOperation getCommentOperationForName(String aName) {\r
+  private synchronized static MirAdminInterfaceLocalizer.MirSimpleEntityOperation\r
+      getCommentOperationForName(String aName) {\r
     try {\r
       if (commentOperations == null) {\r
         commentOperations = new HashMap();\r
         Iterator i = localizer().adminInterface().simpleCommentOperations().iterator();\r
         while (i.hasNext()) {\r
-          MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation = (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();\r
+          MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation =\r
+              (MirAdminInterfaceLocalizer.MirSimpleEntityOperation) i.next();\r
           commentOperations.put(operation.getName(), operation);\r
         }\r
       }\r
@@ -243,6 +272,10 @@ public class MirGlobal {
     return result;\r
   }\r
 \r
+  public static BundleFactory getBundleFactory() {\r
+    return bundleFactory;\r
+  }\r
+\r
   public static void registerLogin(String aName, String anId) {\r
     modifyLoggedInCount(aName, anId, 1);\r
   }\r
@@ -279,6 +312,10 @@ public class MirGlobal {
     }\r
   }\r
 \r
+  /**\r
+   * Called whenever a modifying admin action occurs. Used to log\r
+   * the action, if admin activity logging is turned on,\r
+   */\r
   public static void logAdminUsage(EntityUsers aUser, String anObject, String aDescription) {\r
     try {\r
       if (config().getString("Mir.Admin.LogAdminActivity", "0").equals("1")) {\r
@@ -289,8 +326,23 @@ public class MirGlobal {
       }\r
     }\r
     catch (Throwable t) {\r
-      logger.error("Error while logging admin usage ("+aUser.toString()+", "+aDescription+"): " +t.toString());\r
+      logger.error("Error while logging admin usage ("+\r
+          aUser.toString()+", "+aDescription+"): " +t.toString());\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Reloads all reloadable configurations, such as the producer subsystem.\r
+   */\r
+  public static void reloadConfigurations() throws MirGlobalExc, MirGlobalFailure {\r
+    getProducerEngine().reloadConfiguration();\r
+    try {\r
+      LoggerEngine.reload();\r
+    }\r
+    catch (Throwable e) {\r
+      throw new MirGlobalFailure(e);\r
     }\r
+    getBundleFactory().reload();\r
   }\r
 }\r
 \r
diff --git a/source/mircoders/global/MirGlobalExc.java b/source/mircoders/global/MirGlobalExc.java
new file mode 100755 (executable)
index 0000000..0f7cd75
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mircoders.global;
+
+import multex.Exc;
+
+public class MirGlobalExc extends Exc {
+  public MirGlobalExc(String aMessage) {
+    super(aMessage);
+  }
+}
diff --git a/source/mircoders/global/MirGlobalFailure.java b/source/mircoders/global/MirGlobalFailure.java
new file mode 100755 (executable)
index 0000000..1fcdca4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mircoders.global;
+
+import multex.Failure;
+
+public class MirGlobalFailure extends Failure {
+  public MirGlobalFailure(Throwable aCause){
+    super(aCause.getMessage(), aCause);
+  }
+
+  public MirGlobalFailure(String msg, Exception cause){
+    super(msg,cause);
+  }
+}
index 694fed9..33a6267 100755 (executable)
@@ -30,6 +30,7 @@
 package mircoders.global;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -43,49 +44,97 @@ import mir.producer.Producer;
 import mir.producer.ProducerFactory;
 import mir.util.GeneratorFormatAdapters;
 import mir.util.StringRoutines;
-import multex.Exc;
-import multex.Failure;
-import mircoders.localizer.MirLocalizerExc;
 
 public class ProducerEngine {
   private JobQueue producerJobQueue;
   private LoggerWrapper logger;
-
+  private Map nameToFactory;
+  private List factories;
 
   protected ProducerEngine() {
     logger = new LoggerWrapper("Producer");
     producerJobQueue = new JobQueue(new LoggerWrapper("Producer.Queue"));
-  }
 
-  public void addJob(String aProducerFactory, String aVerb) throws ProducerEngineExc, ProducerEngineFailure {
-    ProducerFactory factory;
+    factories = new ArrayList();
+    nameToFactory = new HashMap();
 
     try {
-      factory = MirGlobal.localizer().producers().getFactoryForName( aProducerFactory );
+      reloadConfiguration();
+    }
+    catch (Throwable t) {
+    }
+  }
+
+  /**
+   * Reloads the producer configuration
+   */
+  public void reloadConfiguration()  throws MirGlobalExc, MirGlobalFailure {
+    try {
+      factories = MirGlobal.localizer().producers().loadFactories();
+
+      synchronized (nameToFactory) {
+        nameToFactory.clear();
+
+        Iterator i = factories.iterator();
+        while (i.hasNext()) {
+          ProducerFactory factory = (ProducerFactory) i.next();
+          nameToFactory.put(factory.getName(), factory);
+        }
+      }
+    }
+    catch (Throwable t) {
+      throw new MirGlobalFailure(t);
     }
-    catch (MirLocalizerExc e) {
-      throw new ProducerEngineFailure(e);
+  }
+
+  /**
+   * Looks up a producer factory by name
+   */
+  private ProducerFactory getFactoryForName(String aName) {
+    synchronized (nameToFactory) {
+      return (ProducerFactory) nameToFactory.get(aName);
     }
+  }
+
+  /**
+   * Returns all factories
+   */
+  public List getFactories() {
+    return factories;
+  }
+  /**
+   * Adds a producer job to the queue
+   */
+  public void addJob(String aProducerFactory, String aVerb) throws MirGlobalExc, MirGlobalFailure {
+    ProducerFactory factory;
+
+    factory = getFactoryForName( aProducerFactory );
 
     if (factory==null)
-      throw new ProducerEngineExc("Unknown producer: " + aProducerFactory);
+      throw new MirGlobalExc("Unknown producer: " + aProducerFactory);
 
     if (!factory.allowVerb(aVerb))
-      throw new ProducerEngineExc("illegal producer/verb combination: " + aProducerFactory+"::"+aVerb);
+      throw new MirGlobalExc("illegal producer/verb combination: " + aProducerFactory+"::"+aVerb);
 
     producerJobQueue.appendJob(
         new ProducerJob(aProducerFactory, aVerb), aProducerFactory+"."+aVerb);
   }
 
+  /**
+   * Cancels a list of jobs by job identifier
+   */
   public void cancelJobs(List aJobs) {
     producerJobQueue.cancelJobs(aJobs);
   };
 
+  /**
+   * Cancels all jobs in the queue
+   */
   public void cancelAllJobs() {
     producerJobQueue.cancelAllJobs();
   };
 
-  public void addTask(ProducerTask aTask) throws ProducerEngineExc, ProducerEngineFailure {
+  public void addTask(ProducerTask aTask) throws MirGlobalExc, MirGlobalFailure {
     addJob(aTask.getProducer(), aTask.getVerb());
   }
 
@@ -184,7 +233,7 @@ public class ProducerEngine {
       logger.info("Producing job: "+factoryName+"."+verb);
 
       try {
-        factory = MirGlobal.localizer().producers().getFactoryForName( factoryName );
+        factory = getFactoryForName(factoryName);
 
         if (factory!=null) {
           MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(startingMap);
@@ -212,22 +261,6 @@ public class ProducerEngine {
     }
   }
 
-  public static class ProducerEngineExc extends Exc {
-    public ProducerEngineExc(String aMessage) {
-      super(aMessage);
-    }
-  }
-
-  public static class ProducerEngineFailure extends Failure {
-    public ProducerEngineFailure(Throwable aCause){
-      super(aCause.getMessage(), aCause);
-    }
-
-    public ProducerEngineFailure(String msg, Exception cause){
-      super(msg,cause);
-    }
-  }
-
   public static class ProducerTask {
     private String producer;
     private String verb;
@@ -245,7 +278,7 @@ public class ProducerEngine {
       return producer;
     }
 
-    public static List parseProducerTaskList(String aList) throws ProducerEngineExc {
+    public static List parseProducerTaskList(String aList) throws MirGlobalExc {
       Iterator i;
       List result = new Vector();
 
@@ -257,7 +290,7 @@ public class ProducerEngine {
           List parts = StringRoutines.splitString(taskExpression, ".");
 
           if (parts.size() != 2)
-            throw new ProducerEngineExc("Invalid producer expression: '" + taskExpression + "'");
+            throw new MirGlobalExc("Invalid producer expression: '" + taskExpression + "'");
           else
             result.add(new ProducerEngine.ProducerTask( (String) parts.get(0), (String) parts.get(1)));
         }
index a322cc3..5dfaa15 100755 (executable)
  */
 package mircoders.localizer;
 
+import mir.entity.adapter.EntityAdapter;
+import mir.generator.Generator;
+
 import java.util.List;
 import java.util.Map;
 
-import mir.entity.adapter.EntityAdapter;
-
 /**
+ * Interface to allow for localized changed to the workings of the admin system
  *
- * <p>Title: Interface to allow for localized changed to the workings of the admin system</p>
  * @author Zapata
- * @version 1.0
  */
 
 public interface MirAdminInterfaceLocalizer {
@@ -70,17 +70,33 @@ public interface MirAdminInterfaceLocalizer {
    * @param aDefault The default generator
    * @return
    */
-  public String getAdminPageGenerator(String aPage, Map aTemplateData, EntityAdapter aUser, String aDefault);
+  public String getAdminPageGenerator(String aPage, Map aTemplateData, EntityAdapter aUser, String aDefault) throws MirLocalizerExc;
 
   /**
+   * Prepares an article preview
    *
-   * @return
+   * @param aPreviewPage there may be different preview pages for a single article.
+   *     (i.e. the same article may lead to different pages) this parameter selects one
+   *      of those versions. See also {@link #getPreviewPages}.
+   * @param anArticle the article to be previewed
+   * @param aContext the context to be supplied to the generator
+   * @return the generator to be used to generate the preview
+   */
+  public Generator prepareArticlePreview(String aPreviewPage, EntityAdapter anArticle, Map aContext)
+      throws MirLocalizerExc, MirLocalizerFailure;
+
+  /**
+   * Return the available preview variations of one article
+   */
+  public List getPreviewPages(EntityAdapter anArticle) throws MirLocalizerExc, MirLocalizerFailure;
+
+  /**
+   * Get the {@link List} of {@link MirSimpleEntityOperation}s available for comments
    */
   public List simpleCommentOperations();
 
   /**
-   *
-   * @return
+   * Get the {@link List} of {@link MirSimpleEntityOperation}s available for articles
    */
   public List simpleArticleOperations();
 
index f5a126c..a9cf39d 100755 (executable)
@@ -33,15 +33,7 @@ import mir.entity.Entity;
 import mir.session.Request;
 
 /**
- *
- *
- * <p>Title: Anti-abuse filter type</p>
- * <p>Description: Interface to define filter types for the anti-abuse system
- *  </p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: Mir coders</p>
- * @author Zapata
- * @version 1.0
+ * Interface to define filter types for the anti-abuse system
  */
 
 public interface MirAntiAbuseFilterType {
index 7d2be0a..e2165af 100755 (executable)
@@ -126,9 +126,9 @@ public class MirCachingLocalizerDecorator implements MirLocalizer {
   private static class MirCachingGeneratorLocalizer implements MirGeneratorLocalizer {
     private MirGeneratorLocalizer master;
     private WriterEngine writerEngine;
-    private Generator.GeneratorLibrary producerGeneratorLibrary;
-    private Generator.GeneratorLibrary adminGeneratorLibrary;
-    private Generator.GeneratorLibrary openPostingGeneratorLibrary;
+    private Generator.Library producerGeneratorLibrary;
+    private Generator.Library adminGeneratorLibrary;
+    private Generator.Library openPostingGeneratorLibrary;
 
     public MirCachingGeneratorLocalizer(MirGeneratorLocalizer aMaster) {
       master = aMaster;
@@ -142,7 +142,7 @@ public class MirCachingLocalizerDecorator implements MirLocalizer {
       return writerEngine;
     };
 
-    public Generator.GeneratorLibrary makeProducerGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
+    public Generator.Library makeProducerGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
       if (producerGeneratorLibrary==null) {
         producerGeneratorLibrary = master.makeProducerGeneratorLibrary();
       }
@@ -150,7 +150,7 @@ public class MirCachingLocalizerDecorator implements MirLocalizer {
       return producerGeneratorLibrary;
     };
 
-    public Generator.GeneratorLibrary makeAdminGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
+    public Generator.Library makeAdminGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
       if (adminGeneratorLibrary==null) {
         adminGeneratorLibrary = master.makeAdminGeneratorLibrary();
       }
@@ -158,7 +158,7 @@ public class MirCachingLocalizerDecorator implements MirLocalizer {
       return adminGeneratorLibrary;
     };
 
-    public Generator.GeneratorLibrary makeOpenPostingGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
+    public Generator.Library makeOpenPostingGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
       if (openPostingGeneratorLibrary==null) {
         openPostingGeneratorLibrary = master.makeOpenPostingGeneratorLibrary();
       }
index 583391e..2065c2a 100755 (executable)
@@ -36,7 +36,7 @@ import mir.generator.WriterEngine;
 public interface MirGeneratorLocalizer {
   public WriterEngine makeWriterEngine() throws MirLocalizerExc, MirLocalizerFailure;
 
-  public Generator.GeneratorLibrary makeProducerGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure;
-  public Generator.GeneratorLibrary makeAdminGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure;
-  public Generator.GeneratorLibrary makeOpenPostingGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure;
+  public Generator.Library makeProducerGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure;
+  public Generator.Library makeAdminGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure;
+  public Generator.Library makeOpenPostingGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure;
 }
\ No newline at end of file
index c8830b3..fccebe3 100755 (executable)
@@ -40,49 +40,23 @@ import mircoders.entity.EntityContent;
 public interface MirOpenPostingLocalizer {
 
   /**
-   * Class to encapsulate a validation error
    *
-   * <p>Title: </p>
-   * <p>Description: </p>
-   * <p>Copyright: Copyright (c) 2003</p>
-   * <p>Company: </p>
-   * @author not attributable
-   * @version 1.0
-   */
-
-  /**
-   *
-   * @param aRequest
-   * @param aSession
-   * @return
-   * @throws MirLocalizerExc
-   * @throws MirLocalizerFailure
    */
   public SessionHandler getOpenSessionHandler(Request aRequest, Session aSession) throws MirLocalizerExc, MirLocalizerFailure;
 
   /**
-   *
-   * @param aComment
-   * @throws MirLocalizerExc
-   * @throws MirLocalizerFailure
+   * This method will be called after a comment has been posted
+   * via the open posting interface.
    */
   public void afterCommentPosting(EntityComment aComment) throws MirLocalizerExc, MirLocalizerFailure;
 
   /**
    * This method will be called after an article is posted via the open posting interface.
-   *
-   * @param aContent
-   * @throws MirLocalizerExc
-   * @throws MirLocalizerFailure
    */
   public void afterContentPosting(EntityContent aContent) throws MirLocalizerExc, MirLocalizerFailure;
 
   /**
    *
-   *
-   * @return
-   * @throws MirLocalizerExc
-   * @throws MirLocalizerFailure
    */
 
   public List getAntiAbuseFilterTypes() throws MirLocalizerExc, MirLocalizerFailure;
index b389f8f..25e600d 100755 (executable)
@@ -31,11 +31,12 @@ package mircoders.localizer;
 
 import java.util.List;
 
-import mir.producer.ProducerFactory;
-
 public interface MirProducerLocalizer {
-  public List factories() throws MirLocalizerExc, MirLocalizerFailure;
-  public ProducerFactory getFactoryForName(String aName);
+  /**
+   * Loads the factories. Should return a list of implementations of
+   *     {@link mir.producer.ProducerFactory}
+   */
+  public List loadFactories() throws MirLocalizerExc, MirLocalizerFailure;
 
   public List getRecipeNames() throws MirLocalizerExc, MirLocalizerFailure;
   public void produceRecipe(String aName) throws MirLocalizerExc, MirLocalizerFailure;
index 224d980..b4a50df 100755 (executable)
 
 package mircoders.localizer.basic;
 
-import java.util.Arrays;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Vector;
-
+import mir.bundle.Bundle;
+import mir.config.MirPropertiesConfiguration;
 import mir.entity.Entity;
 import mir.entity.adapter.EntityAdapter;
+import mir.entity.adapter.EntityAdapterExc;
+import mir.generator.Generator;
+import mir.generator.GeneratorExc;
 import mir.log.LoggerWrapper;
 import mir.misc.StringUtil;
+import mir.module.ModuleExc;
 import mir.storage.StorageObjectFailure;
 import mir.util.DateTimeFunctions;
 import mir.util.EntityUtility;
+import mir.util.StringRoutines;
+import mir.util.generator.BundleGeneratorFunction;
 import mircoders.entity.EntityComment;
 import mircoders.entity.EntityContent;
 import mircoders.global.MirGlobal;
 import mircoders.localizer.MirAdminInterfaceLocalizer;
 import mircoders.localizer.MirLocalizerExc;
 import mircoders.localizer.MirLocalizerFailure;
+import mircoders.module.ModuleLanguage;
 import mircoders.storage.DatabaseContent;
 
+import java.util.*;
+
 
 public class MirBasicAdminInterfaceLocalizer implements MirAdminInterfaceLocalizer {
-  private Vector simpleCommentOperations;
-  private Vector simpleArticleOperations;
+  /** preview page name (String) -> generator name (String) */
+  private Map previewPages;
+  private List previewPageNames;
+
+  private List simpleCommentOperations;
+  private List simpleArticleOperations;
   private Map simpleCommentOperationsMap;
   private Map simpleArticleOperationsMap;
+
   protected static LoggerWrapper logger = new LoggerWrapper("Localizer.AdminInterface");;
+  protected MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
 
-  public MirBasicAdminInterfaceLocalizer() throws MirLocalizerFailure, MirLocalizerExc {
+  public MirBasicAdminInterfaceLocalizer() throws MirLocalizerFailure {
 
-    simpleCommentOperations = new Vector();
-    simpleArticleOperations = new Vector();
+    simpleCommentOperations = new ArrayList();
+    simpleArticleOperations = new ArrayList();
     simpleCommentOperationsMap = new HashMap();
     simpleArticleOperationsMap = new HashMap();
 
+    previewPages = new HashMap();
+    previewPageNames = new ArrayList();
+
+    String[] previewConfiguration = configuration.getStringArray("Mir.Localizer.Admin.ArticlePreview");
+
+    for (int i = 0; i<previewConfiguration.length; i++) {
+      try {
+        List parts = StringRoutines.separateString(previewConfiguration[i], "=");
+        if (parts.size() == 2) {
+          String key = ((String) parts.get(0)).trim();
+          previewPages.put(key,((String) parts.get(1)).trim());
+          previewPageNames.add(key);
+        }
+        else {
+          throw new Exception("'=' expected");
+        }
+      }
+      catch (Exception e) {
+        logger.error("Error while processing preview configuration '" + previewConfiguration[i] + "': " + e.toString());
+      }
+    }
+
     addSimpleArticleOperation(new ChangeArticleFieldOperation("newswire", "to_article_type", "0", "1", false));
     addSimpleArticleOperation(new ModifyArticleFieldOperation("unhide", "is_published", "1", false));
     addSimpleArticleOperation(new ModifyArticleFieldOperation("hide", "is_published", "0", false));
@@ -78,10 +107,59 @@ public class MirBasicAdminInterfaceLocalizer implements MirAdminInterfaceLocaliz
     addSimpleCommentOperation(new ModifyCommentFieldOperation("hide", "is_published", "0"));
   }
 
-  public String getAdminPageGenerator(String aPage, Map aTemplateData, EntityAdapter aUser, String aDefault) {
+  /** {@inheritDoc} */
+  public String getAdminPageGenerator(String aPage, Map aTemplateData, EntityAdapter aUser, String aDefault) throws MirLocalizerExc {
     return aDefault;
   }
 
+  /** {@inheritDoc} */
+  public Generator prepareArticlePreview(String aPreviewPage, EntityAdapter anArticle, Map aContext) throws MirLocalizerExc {
+    MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(aContext);
+    aContext.put("article", anArticle);
+
+
+    try {
+      aContext.put(
+          "language",
+          MirGlobal.localizer().dataModel().adapterModel().makeEntityAdapter("language",
+              new ModuleLanguage().languageForCode(configuration.getString("Mir.Localizer.Admin.ArticlePreviewLanguage"))));
+    }
+    catch (EntityAdapterExc e) {
+      throw new MirLocalizerFailure("Can't create entity adapter", e);
+    }
+    catch (ModuleExc e) {
+      throw new MirLocalizerFailure("Can't find language", e);
+    }
+    aContext.put("pathprefix", configuration.getString("Mir.Localizer.Admin.ArticlePreviewLanguage")); 
+
+    aContext.put("lang",
+        new BundleGeneratorFunction(
+            new Bundle[] {
+              MirGlobal.getBundleFactory().getBundle(
+                  "etc/bundles/producer",
+                  new String[] {
+                    configuration.getString("Mir.Localizer.Admin.ArticlePreviewLanguage") }) }));
+
+
+    if (previewPages.containsKey(aPreviewPage)) {
+      try {
+        return MirGlobal.localizer().generators().makeAdminGeneratorLibrary().makeGenerator((String) previewPages.get(aPreviewPage));
+      }
+      catch (GeneratorExc e) {
+        throw new MirLocalizerFailure(e);
+      }
+    }
+    else {
+      throw new MirLocalizerExc("Unknown preview: " + aPreviewPage);
+    }
+  }
+
+  /** {@inheritDoc} */
+  public List getPreviewPages(EntityAdapter anArticle) throws MirLocalizerExc{
+    return Collections.unmodifiableList(previewPageNames);
+  }
+
+  /** {@inheritDoc} */
   public String makePasswordDigest(String aPassword) {
     return aPassword;
   }
@@ -92,11 +170,11 @@ public class MirBasicAdminInterfaceLocalizer implements MirAdminInterfaceLocaliz
   };
 
   public List simpleCommentOperations() {
-    return simpleCommentOperations;
+    return Collections.unmodifiableList(simpleCommentOperations);
   };
 
   public List simpleArticleOperations() {
-    return simpleArticleOperations;
+    return Collections.unmodifiableList(simpleArticleOperations);
   };
 
   public MirSimpleEntityOperation simpleArticleOperationForName(String aName) {
@@ -254,7 +332,7 @@ public class MirBasicAdminInterfaceLocalizer implements MirAdminInterfaceLocaliz
   protected static class SetCommentFieldsOperation extends CommentModifyingOperation {
     private Map values;
 
-    public SetCommentFieldsOperation(String aName, String aFields[], String aValues[]) throws MirLocalizerExc {
+    public SetCommentFieldsOperation(String aName, String aFields[], String aValues[]) {
       super(aName);
 
       values = new HashMap();
index 2ab4d57..3fae846 100755 (executable)
 package mircoders.localizer.basic;
 
 import gnu.regexp.RE;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
 import mir.entity.Entity;
+import mir.log.LoggerWrapper;
 import mir.session.Request;
 import mir.util.InternetFunctions;
 import mircoders.localizer.MirAntiAbuseFilterType;
 
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
 
 /**
- * <p>Title: </p>
- * <p>Description: </p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: </p>
- * @author not attributable
- * @version 1.0
+ * Wrapper around a collection of common filter classes for Mir's
+ * anti-abuse filtering system.
  */
-
 public class MirBasicAntiAbuseFilterTypes {
+  protected static final LoggerWrapper logger = new LoggerWrapper("Localizer.ProducerAssistant");
+
   private MirBasicAntiAbuseFilterTypes() {
   }
 
@@ -69,20 +66,18 @@ public class MirBasicAntiAbuseFilterTypes {
 
   /**
    * A basic ip filter. Supports x.x.x.x, x.x.x.x/x and x.x.x.x/x.x.x.x expressions.
-   *
-   * <p>Title: </p>
-   * <p>Description: </p>
-   * <p>Copyright: Copyright (c) 2003</p>
-   * <p>Company: </p>
-   * @author not attributable
-   * @version 1.0
    */
-
   public static class IPFilter extends BasicFilterType {
+    /**
+     *
+     */
     public IPFilter(String aName) {
       super(aName);
     }
 
+    /**
+     *
+     */
     public boolean validate(String anExpression) {
       try {
         InternetFunctions.isIpAddressInNetwork("1.1.1.1", anExpression);
@@ -93,6 +88,9 @@ public class MirBasicAntiAbuseFilterTypes {
       }
     };
 
+    /**
+     *
+     */
     public boolean test(String anExpression, Entity anEntity, Request aRequest) {
       try {
         return InternetFunctions.isIpAddressInNetwork(aRequest.getHeader("ip"), anExpression);
@@ -105,15 +103,7 @@ public class MirBasicAntiAbuseFilterTypes {
 
   /**
    * A regular expression filter.
-   *
-   * <p>Title: </p>
-   * <p>Description: </p>
-   * <p>Copyright: Copyright (c) 2003</p>
-   * <p>Company: </p>
-   * @author not attributable
-   * @version 1.0
    */
-
   public static class RegularExpressionFilter extends BasicFilterType {
     private boolean exactMatch;
     private boolean caseSensitive;
@@ -159,11 +149,11 @@ public class MirBasicAntiAbuseFilterTypes {
         Iterator j;
         int flags = 0;
 
-        if (caseSensitive)
-          // TODO jlint says this operator is useless
+        if (!caseSensitive) {
           flags |= RE.REG_ICASE;
+        }
 
-        RE regularExpression = new RE(anExpression, RE.REG_ICASE);
+        RE regularExpression = new RE(anExpression, flags);
 
         switch (fieldKind) {
           case REQUEST_HEADERS:
@@ -171,7 +161,8 @@ public class MirBasicAntiAbuseFilterTypes {
               j = selectedFields.iterator();
 
               while (j.hasNext()) {
-                String field = aRequest.getHeader( (String) j.next());
+                String fieldName = (String) j.next();
+                String field = aRequest.getHeader(fieldName);
 
                 if (exactMatch) {
                   if (field != null && regularExpression.isMatch(field)) {
index dac7f83..8f5ac49 100755 (executable)
 
 package mircoders.localizer.basic;
 
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
 import mir.entity.Entity;
 import mir.misc.StringUtil;
-import mir.session.Request;
-import mir.session.Response;
-import mir.session.Session;
-import mir.session.SessionExc;
-import mir.session.SessionFailure;
-import mir.session.UploadedFile;
-import mir.session.ValidationHelper;
+import mir.session.*;
+import mir.util.EntityUtility;
 import mircoders.entity.EntityContent;
 import mircoders.global.MirGlobal;
 import mircoders.media.MediaUploadProcessor;
 import mircoders.module.ModuleArticleType;
 import mircoders.module.ModuleContent;
 import mircoders.module.ModuleMediafolder;
-import mircoders.storage.DatabaseArticleType;
-import mircoders.storage.DatabaseContent;
-import mircoders.storage.DatabaseContentToMedia;
-import mircoders.storage.DatabaseContentToTopics;
-import mircoders.storage.DatabaseMediafolder;
+import mircoders.storage.*;
+
+import java.util.*;
 
 /**
- *
- * <p>Title: Experimental session handler for article postings </p>
- * <p>Description: </p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: </p>
- * @author Zapata
- * @version 1.0
+ * Extensible handler for open article postings
  */
 
 public class MirBasicArticlePostingHandler extends MirBasicPostingSessionHandler {
-  protected ModuleContent contentModule = new ModuleContent(DatabaseContent.getInstance());
+  protected ModuleContent contentModule = new ModuleContent();
   protected DatabaseContentToMedia contentToMedia = DatabaseContentToMedia.getInstance();
   protected DatabaseContent contentDatabase = DatabaseContent.getInstance();
 
   public MirBasicArticlePostingHandler() {
-    super();
+    this(false);
+  }
+
+  public MirBasicArticlePostingHandler(boolean aPersistentUploadedFiles) {
+    super(aPersistentUploadedFiles);
 
     setResponseGenerators(
       configuration.getString("Localizer.OpenSession.article.EditTemplate"),
@@ -81,11 +66,13 @@ public class MirBasicArticlePostingHandler extends MirBasicPostingSessionHandler
       configuration.getString("Localizer.OpenSession.article.UnsupportedMediaTemplate"),
       configuration.getString("Localizer.OpenSession.article.DoneTemplate"));
   }
-
+  /**
+   * {@inheritDoc}
+   */
   protected void initializeResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     super.initializeResponseData(aRequest, aSession, aResponse);
 
-    Iterator i = DatabaseContent.getInstance().getFields().iterator();
+    Iterator i = DatabaseContent.getInstance().getFieldNames().iterator();
     while (i.hasNext()) {
       String field = (String) i.next();
       aResponse.setResponseValue(field, aRequest.getParameter(field));
@@ -93,6 +80,9 @@ public class MirBasicArticlePostingHandler extends MirBasicPostingSessionHandler
     aResponse.setResponseValue("to_topic", aRequest.getParameters("to_topic"));
   }
 
+  /**
+   * {@inheritDoc}
+   */
   public void validate(List aResults, Request aRequest, Session aSession) throws SessionExc, SessionFailure {
     super.validate(aResults, aRequest, aSession);
 
@@ -102,6 +92,10 @@ public class MirBasicArticlePostingHandler extends MirBasicPostingSessionHandler
     ValidationHelper.testFieldEntered(aRequest, "content_data", "validationerror.missing", aResults);
   }
 
+  /**
+   * Called just before the article is stored in the database.
+   * The last opportunity to alter fields.
+   */
   public void finalizeArticle(Request aRequest, Session aSession, EntityContent anArticle) throws SessionExc, SessionFailure {
     try {
       anArticle.setFieldValue("is_published", "1");
@@ -110,7 +104,7 @@ public class MirBasicArticlePostingHandler extends MirBasicPostingSessionHandler
       anArticle.setFieldValue("is_html", "0");
       anArticle.setFieldValue("publish_path", StringUtil.webdbDate2path(anArticle. getFieldValue("date")));
 
-      ModuleArticleType module = new ModuleArticleType(DatabaseArticleType.getInstance());
+      ModuleArticleType module = new ModuleArticleType();
       anArticle.setFieldValue("to_article_type", module.articleTypeIdForName(configuration.getString("Localizer.OpenSession.article.DefaultArticleType")));
       anArticle.setFieldValue("to_publisher", "1");
     }
@@ -119,12 +113,16 @@ public class MirBasicArticlePostingHandler extends MirBasicPostingSessionHandler
     }
   }
 
-  public void setArticleTopics(Request aRequest, Session aSession, EntityContent aContent) throws SessionExc, SessionFailure {
+  /**
+   * Extracts topics from the request and associated the
+   * article to them.
+   */
+  public void setArticleTopics(Request aRequest, Session aSession, EntityContent anArticle) throws SessionExc, SessionFailure {
     // topics:
     List topics = aRequest.getParameters("to_topic");
     if (topics.size() > 0) {
       try {
-        DatabaseContentToTopics.getInstance().setTopics(aContent.getId(), topics);
+        DatabaseContentToTopics.getInstance().setTopics(anArticle.getId(), topics);
       }
       catch (Throwable e) {
         logger.error("setting content_x_topic failed");
@@ -149,24 +147,29 @@ public class MirBasicArticlePostingHandler extends MirBasicPostingSessionHandler
       }
       aSession.setAttribute("content", article);
 
-
       setArticleTopics(aRequest, aSession, article);
-
     }
     catch (Throwable t) {
       throw new SessionFailure(t);
     }
   }
 
-  public void processUploadedFile(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {
+  public void processAttachmentError(Request aRequest, Session aSession, Attachment aFile, Throwable anError) {
+    EntityUtility.appendLineToField( ((EntityContent) aSession.getAttribute("content")), "comment",
+        "error with attachment: " + anError.toString());
+   ((EntityContent) aSession.getAttribute("content")).update();
+  }
+
+  public void processAttachment(Request aRequest, Session aSession, Attachment aFile) throws SessionExc, SessionFailure {
     try {
       Map values = new HashMap();
-      values.put("title", aRequest.getParameter(aFile.getFieldName()+"_title"));
+      values.put("creator", aRequest.getParameter("creator"));
+      values.putAll(aFile.getAllAttributes());
       values.put("creator", aRequest.getParameter("creator"));
       values.put("to_publisher", "0");
       values.put("is_published", "1");
       values.put("is_produced", "1");
-      ModuleMediafolder module = new ModuleMediafolder(DatabaseMediafolder.getInstance());
+      ModuleMediafolder module = new ModuleMediafolder();
       values.put("to_media_folder", module.mediaFolderIdForName(configuration.getString("Localizer.OpenSession.article.DefaultMediaFolder")));
 
       Entity mediaItem = MediaUploadProcessor.processMediaUpload(aFile, values);
index 8e4cdcb..f8c49fe 100755 (executable)
@@ -36,7 +36,10 @@ import mir.session.SessionExc;
 import mir.session.SessionFailure;
 import mircoders.entity.EntityContent;
 
-
+/**
+ * Handler for open postings of "child articles", that is articles
+ * linked to other articles. Used frequently for translations.
+ */
 public class MirBasicChildArticlePostingHandler extends MirBasicArticlePostingHandler {
   public MirBasicChildArticlePostingHandler() {
     super();
@@ -44,12 +47,25 @@ public class MirBasicChildArticlePostingHandler extends MirBasicArticlePostingHa
     setNormalResponseGenerator(configuration.getString("Localizer.OpenSession.article.EditTemplate"));
   }
 
+  /**
+   * {@inheritDoc}
+   *
+   * <p>
+   * This class overrides this method to set the parent article.
+   */
   public void finalizeArticle(Request aRequest, Session aSession, EntityContent anArticle) throws SessionExc, SessionFailure {
     super.finalizeArticle(aRequest, aSession, anArticle);
 
     anArticle.setFieldValue("to_content", (String) aSession.getAttribute("to_content"));
   }
 
+  /**
+   * {@inheritDoc}
+   *
+   * <p>
+   * Overridden by this class to retrieve and store the to be associated
+   * parent article for subsequent usage.
+   */
   protected void initializeSession(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
     super.initializeSession(aRequest, aSession);
 
index 3e6e6a3..3661b97 100755 (executable)
  */
 package mircoders.localizer.basic;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
 import mir.entity.Entity;
-import mir.session.Request;
-import mir.session.Response;
-import mir.session.Session;
-import mir.session.SessionExc;
-import mir.session.SessionFailure;
-import mir.session.UploadedFile;
-import mir.session.ValidationHelper;
+import mir.session.*;
+import mir.util.EntityUtility;
 import mircoders.entity.EntityComment;
+import mircoders.entity.EntityContent;
 import mircoders.global.MirGlobal;
 import mircoders.media.MediaUploadProcessor;
 import mircoders.module.ModuleComment;
 import mircoders.module.ModuleCommentStatus;
 import mircoders.module.ModuleMediafolder;
-import mircoders.storage.DatabaseComment;
-import mircoders.storage.DatabaseCommentStatus;
-import mircoders.storage.DatabaseCommentToMedia;
-import mircoders.storage.DatabaseContent;
-import mircoders.storage.DatabaseMediafolder;
+import mircoders.storage.*;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
  *
@@ -65,12 +57,17 @@ import mircoders.storage.DatabaseMediafolder;
  */
 
 public class MirBasicCommentPostingHandler extends MirBasicPostingSessionHandler {
-  protected ModuleComment commentModule = new ModuleComment(DatabaseComment.getInstance());
+  protected ModuleComment commentModule = new ModuleComment();
   protected DatabaseCommentToMedia commentToMedia = DatabaseCommentToMedia.getInstance();
 
 
   public MirBasicCommentPostingHandler() {
-    super();
+    this(false);
+  }
+
+
+  public MirBasicCommentPostingHandler(boolean aPersistentUploadedFiles) {
+    super(aPersistentUploadedFiles);
 
     setResponseGenerators(
       configuration.getString("Localizer.OpenSession.comment.EditTemplate"),
@@ -82,7 +79,7 @@ public class MirBasicCommentPostingHandler extends MirBasicPostingSessionHandler
   protected void initializeResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     super.initializeResponseData(aRequest, aSession, aResponse);
 
-    Iterator i = DatabaseComment.getInstance().getFields().iterator();
+    Iterator i = DatabaseComment.getInstance().getFieldNames().iterator();
     while (i.hasNext()) {
       String field = (String) i.next();
       aResponse.setResponseValue(field, aRequest.getParameter(field));
@@ -110,7 +107,7 @@ public class MirBasicCommentPostingHandler extends MirBasicPostingSessionHandler
   public void finalizeComment(Request aRequest, Session aSession, EntityComment aComment) throws SessionExc, SessionFailure {
     try {
       aComment.setFieldValue("is_published", "1");
-      ModuleCommentStatus module = new ModuleCommentStatus(DatabaseCommentStatus.getInstance());
+      ModuleCommentStatus module = new ModuleCommentStatus();
       aComment.setFieldValue("to_comment_status", module.commentStatusIdForName(configuration.getString("Localizer.OpenSession.comment.DefaultCommentStatus")));
       aComment.setFieldValue("is_html", "0");
       aComment.setFieldValue("to_media", (String) aSession.getAttribute("to_media"));
@@ -140,14 +137,14 @@ public class MirBasicCommentPostingHandler extends MirBasicPostingSessionHandler
     }
   }
 
-  public void processUploadedFile(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {
+  public void processAttachment(Request aRequest, Session aSession, Attachment aFile) throws SessionExc, SessionFailure {
     try {
       Map values = new HashMap();
-      values.put("title", aRequest.getParameter(aFile.getFieldName()+"_title"));
       values.put("creator", aRequest.getParameter("creator"));
+      values.putAll(aFile.getAllAttributes());
       values.put("to_publisher", "0");
       values.put("is_published", "1");
-      ModuleMediafolder module = new ModuleMediafolder(DatabaseMediafolder.getInstance());
+      ModuleMediafolder module = new ModuleMediafolder();
       values.put("to_media_folder", module.mediaFolderIdForName(configuration.getString("Localizer.OpenSession.comment.DefaultMediaFolder")));
 
       Entity mediaItem = MediaUploadProcessor.processMediaUpload(aFile, values);
@@ -159,6 +156,13 @@ public class MirBasicCommentPostingHandler extends MirBasicPostingSessionHandler
     }
   }
 
+  public void processAttachmentError(Request aRequest, Session aSession, Attachment aFile, Throwable anError) {
+    EntityUtility.appendLineToField( ((EntityComment) aSession.getAttribute("comment")), "comment",
+        "error with attachment: " + anError.toString());
+
+    ((EntityComment) aSession.getAttribute("comment")).update();
+  }
+
   public void postProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
     EntityComment comment = (EntityComment) aSession.getAttribute("comment");
 
index 25d85e0..4a41049 100755 (executable)
  */\r
 package mircoders.localizer.basic;\r
 \r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Vector;\r
-\r
 import mir.config.MirPropertiesConfiguration;\r
 import mir.entity.Entity;\r
 import mir.entity.adapter.EntityAdapter;\r
 import mir.entity.adapter.EntityAdapterDefinition;\r
 import mir.entity.adapter.EntityAdapterModel;\r
+import mir.generator.Generator;\r
+import mir.generator.GeneratorExc;\r
+import mir.generator.GeneratorFailure;\r
 import mir.log.LoggerWrapper;\r
 import mir.media.MediaHandler;\r
 import mir.misc.NumberUtils;\r
+import mir.util.JDBCStringRoutines;\r
 import mir.util.ParameterExpander;\r
 import mir.util.RewindableIterator;\r
 import mir.util.StructuredContentParser;\r
@@ -54,40 +52,16 @@ import mircoders.localizer.MirLocalizerExc;
 import mircoders.localizer.MirLocalizerFailure;\r
 import mircoders.media.MediaHelper;\r
 import mircoders.module.ModuleContent;\r
-import mircoders.storage.DatabaseArticleType;\r
-import mircoders.storage.DatabaseAudio;\r
-import mircoders.storage.DatabaseBreaking;\r
-import mircoders.storage.DatabaseComment;\r
-import mircoders.storage.DatabaseCommentStatus;\r
-import mircoders.storage.DatabaseContent;\r
-import mircoders.storage.DatabaseContentToMedia;\r
-import mircoders.storage.DatabaseContentToTopics;\r
-import mircoders.storage.DatabaseImageType;\r
-import mircoders.storage.DatabaseImages;\r
-import mircoders.storage.DatabaseLanguage;\r
-import mircoders.storage.DatabaseMediaType;\r
-import mircoders.storage.DatabaseMediafolder;\r
-import mircoders.storage.DatabaseMessages;\r
-import mircoders.storage.DatabaseOther;\r
-import mircoders.storage.DatabaseTopics;\r
-import mircoders.storage.DatabaseUploadedMedia;\r
-import mircoders.storage.DatabaseUsers;\r
-import mircoders.storage.DatabaseVideo;\r
-\r
-public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {\r
-  protected LoggerWrapper logger;\r
-  protected MirPropertiesConfiguration configuration;\r
+import mircoders.module.ModuleLanguage;\r
+import mircoders.storage.*;\r
+import multex.Failure;\r
 \r
-  public MirBasicDataModelLocalizer() throws MirLocalizerFailure, MirLocalizerExc {\r
-    logger = new LoggerWrapper("Localizer.DataModel");\r
+import java.util.*;\r
 \r
-    try {\r
-      configuration = MirPropertiesConfiguration.instance();\r
-    }\r
-    catch (Throwable e) {\r
-      throw new MirLocalizerFailure("Can't get configuration: " + e.getMessage(), e);\r
-    }\r
-  }\r
+public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {\r
+  protected LoggerWrapper logger = new LoggerWrapper("Localizer.DataModel");\r
+  protected MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();\r
+  protected ModuleLanguage languageModule = new ModuleLanguage();\r
 \r
   protected void constructContentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure, MirLocalizerExc {\r
     try {\r
@@ -139,12 +113,32 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
 \r
       anEntityAdapterDefinition.addCalculatedField("operations",\r
           new EntityToSimpleOperationsField(MirGlobal.localizer().adminInterface().simpleArticleOperations()));\r
+      \r
+      anEntityAdapterDefinition.addCalculatedField("languagename", new ContentToLanguageNameField());\r
+\r
+      anEntityAdapterDefinition.addCalculatedField("is_original", new ContentIsOriginalField());\r
+      anEntityAdapterDefinition.addCalculatedField("to_original", new ContentToOriginalField());\r
+      anEntityAdapterDefinition.addCalculatedField("to_translations", new ContentToTranslationsField());\r
+      anEntityAdapterDefinition.addCalculatedField("to_translation", new ContentToTranslationField());\r
+\r
+      anEntityAdapterDefinition.addCalculatedField("previews", new EntityAdapterDefinition.CalculatedField() {\r
+        public Object getValue(EntityAdapter anEntityAdapter) {\r
+          try {\r
+            return MirGlobal.localizer().adminInterface().getPreviewPages(anEntityAdapter);\r
+          }\r
+          catch (MirLocalizerExc e) {\r
+            throw new Failure("Cannot get previews for article", e);\r
+          }\r
+        }\r
+      });\r
     }\r
     catch (Throwable t) {\r
       throw new MirLocalizerFailure(t.getMessage(), t);\r
     }\r
   }\r
 \r
+\r
+\r
   protected void constructCommentAdapterDefinition(EntityAdapterDefinition anEntityAdapterDefinition) throws MirLocalizerFailure {\r
     try {\r
       anEntityAdapterDefinition.addDBDateField("creationdate", "webdb_create", configuration.getString("Mir.DefaultTimezone"));\r
@@ -228,6 +222,7 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
       definition.addCalculatedField("info", new MediaToMediaInfoField());\r
       definition.addCalculatedField("big_icon", new MediaToBigIconField());\r
       result.addMapping( "video", DatabaseVideo.getInstance(), definition);\r
+\r
       definition = new EntityAdapterDefinition();\r
       definition.addCalculatedField("mediafolder", new MediaToMediaFolderField());\r
       definition.addCalculatedField("human_readable_size", new HumanReadableSizeField("value"));\r
@@ -249,8 +244,6 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
       definition.addCalculatedField("structuredProfile", new StructuredContentField("profile"));\r
       result.addMapping( "user", DatabaseUsers.getInstance(), definition);\r
 \r
-      result.addMapping( "otherMedia", DatabaseOther.getInstance(), new EntityAdapterDefinition());\r
-\r
       result.addMapping( "content_x_topic", DatabaseContentToTopics.getInstance(), new EntityAdapterDefinition());\r
 \r
     }\r
@@ -807,7 +800,7 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
     private ModuleContent contentModule;\r
 \r
     public ContentToIsLockedField() {\r
-      contentModule = new ModuleContent(DatabaseContent.getInstance());\r
+      contentModule = new ModuleContent();\r
     }\r
 \r
     public Object getValue(EntityAdapter anEntityAdapter) {\r
@@ -819,4 +812,119 @@ public class MirBasicDataModelLocalizer implements MirDataModelLocalizer {
       }\r
     }\r
   }\r
+    protected class ContentIsOriginalField implements EntityAdapterDefinition.CalculatedField {\r
+    public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
+      try {\r
+\r
+        //ML: add check on article type\r
+        boolean result = (anEntityAdapter.get("parent")==null);\r
+\r
+        return new Boolean(result);\r
+      }\r
+      catch (Throwable t) {\r
+        throw new MirLocalizerFailure(t);\r
+      }\r
+    }\r
+  }\r
+\r
+  protected class ContentToOriginalField implements EntityAdapterDefinition.CalculatedField {\r
+    public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
+      try {\r
+        if (anEntityAdapter.get("parent")!=null)\r
+          return anEntityAdapter.get("parent");\r
+        else\r
+          return anEntityAdapter;\r
+      }\r
+      catch (Throwable t) {\r
+        throw new MirLocalizerFailure(t);\r
+      }\r
+    }\r
+  }\r
+\r
+  protected class ContentToTranslationsField implements EntityAdapterDefinition.CalculatedField {\r
+    public Object getValue(EntityAdapter anEntityAdapter) {\r
+      try {\r
+        return anEntityAdapter.getRelation(\r
+                    "is_published='t' and to_content="+anEntityAdapter.get("id"),\r
+                    "id",\r
+                    "content" );\r
+      }\r
+      catch (Throwable t) {\r
+        throw new RuntimeException(t.getMessage());\r
+      }\r
+    }\r
+  }\r
+\r
+  protected class ContentToLanguageNameField implements EntityAdapterDefinition.CalculatedField {\r
+    public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
+      try {\r
+        String result = "";\r
+        EntityAdapter language = (EntityAdapter) anEntityAdapter.get("language");\r
+        if (language != null) {\r
+          if (language.get("code").equals("ot")) {\r
+            result = ((String) anEntityAdapter.get("subtitle")).trim();\r
+            if (result == null || result.equals(""))\r
+              result = (String) language.get("name");\r
+          } else {\r
+            result = (String) language.get("name");\r
+          }\r
+        }\r
+\r
+        return result;\r
+      }\r
+      catch (Throwable t) {\r
+        throw new MirLocalizerFailure(t);\r
+      }\r
+    }\r
+  }\r
+\r
+  protected class ContentToTranslationFunction implements Generator.Function {\r
+    private EntityAdapter target;\r
+    private String targetId;\r
+    private String targetLanguageId;\r
+\r
+    public ContentToTranslationFunction(EntityAdapter aTarget) {\r
+      target = aTarget;\r
+      targetId = (String) target.get("id");\r
+      targetLanguageId = (String) target.get("to_language");\r
+    }\r
+\r
+    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {\r
+      if (aParameters.size()!=1 || !(aParameters.get(0) instanceof String))\r
+        throw new GeneratorExc("1 string parameter expected");\r
+\r
+      try {\r
+        String language = (String) aParameters.get(0);\r
+        String languageId = languageModule.languageIdForCode(language);\r
+        Object result = null;\r
+\r
+        if (languageId != null && !targetLanguageId.equals(languageId)) {\r
+          result = target.getToOneRelation(\r
+              "is_published='t' and to_content=" + targetId + " and to_language='" + JDBCStringRoutines.escapeStringLiteral(languageId) + "'",\r
+              "id", "content");\r
+        }\r
+\r
+        if (result == null)\r
+          result = target;\r
+\r
+        return result;\r
+      }\r
+      catch (Throwable t) {\r
+        t.printStackTrace(System.out);\r
+        throw new GeneratorFailure(t);\r
+      }\r
+    }\r
+  }\r
+\r
+  protected class ContentToTranslationField implements EntityAdapterDefinition.CalculatedField {\r
+    public Object getValue(EntityAdapter anEntityAdapter) throws MirLocalizerFailure {\r
+      try {\r
+        return new ContentToTranslationFunction((EntityAdapter) anEntityAdapter.get("to_original"));\r
+      }\r
+      catch (Throwable t) {\r
+        throw new MirLocalizerFailure(t);\r
+      }\r
+    }\r
+  }\r
 }\r
+\r
index 73bea17..39d0908 100755 (executable)
@@ -37,6 +37,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Vector;
+import java.util.Collections;
 
 import mir.config.MirPropertiesConfiguration;
 import mir.generator.Generator;
@@ -59,7 +60,6 @@ import mircoders.storage.DatabaseContent;
 
 import org.apache.commons.net.smtp.SMTPClient;
 import org.apache.commons.net.smtp.SMTPReply;
-import org.apache.struts.util.MessageResources;
 
 
 /**
@@ -84,11 +84,11 @@ public class MirBasicEmailArticleHandler implements SessionHandler {
     }
     catch (Throwable t) {
       logger.fatal("Cannot load configuration: " + t.toString());
-      
+
       throw new RuntimeException("Cannot load configuration: " + t.toString());
     }
   }
-  
+
   public void processRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     if (aSession.getAttribute("initialRequest") == null) {
       aSession.setAttribute("initialRequest", "no");
@@ -98,17 +98,17 @@ public class MirBasicEmailArticleHandler implements SessionHandler {
       subsequentRequest(aRequest, aSession, aResponse);
     }
   }
-  
+
   protected void initialRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     initializeSession(aRequest, aSession);
     makeInitialResponse(aRequest, aSession, aResponse);
   }
-  
+
   protected void initializeSession(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
     /* do nothing for now */
-    
+
   }
-  
+
   protected void makeInitialResponse(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     /* if you do not supply an aid to this handler, it should return an error page */
     /* if you supply a non-functioning/non-published  aid to this handler, it should return an error page, but at a
@@ -121,20 +121,20 @@ public class MirBasicEmailArticleHandler implements SessionHandler {
     else {
       aSession.setAttribute("email.aid",articleID);
       aResponse.setResponseValue("errors", null);
-      
-      String mail_language = configuration.getString("Mir.Login.DefaultLanguage", "en");       
+
+      String mail_language = configuration.getString("Mir.Login.DefaultLanguage", "en");
       aResponse.setResponseValue("mail_language",mail_language);
       aResponse.setResponseValue("mail_to","");
       aResponse.setResponseValue("mail_from","");
       aResponse.setResponseValue("mail_from_name","");
       aResponse.setResponseValue("mail_comment","");
-      
+
       aResponse.setResponseGenerator(configuration.getString("Localizer.OpenSession.email.PrepareTemplate"));
 
-      
+
     }
   }
-  
+
   protected boolean shouldSendMail(Request aRequest, Session aSession, Response aResponse,List aValidationErrors) throws SessionExc, SessionFailure{
     if (validate(aRequest,aSession,aResponse,aValidationErrors)){
       String to=aRequest.getParameter("mail_to");
@@ -142,22 +142,22 @@ public class MirBasicEmailArticleHandler implements SessionHandler {
          || to.indexOf('\n') != -1
           || to.indexOf('\r') != -1
           || to.indexOf(',') != -1) {
-       throw new SessionExc("Invalid to address"); // we might want to see this in a log, so it is not a validation error 
+       throw new SessionExc("Invalid to address"); // we might want to see this in a log, so it is not a validation error
       }
       else return true; // go for it
     }
     else{
       return false; //validation failed, but not in a potentially abusive way
     }
-    
+
   }
-  
-    
+
+
 
 
 
   protected boolean validate(Request aRequest, Session aSession, Response aResponse,List aValidationErrors) throws SessionExc, SessionFailure{
-    
+
     if (ValidationHelper.testFieldEntered(aRequest, "mail_to", "validationerror.missing", aValidationErrors))
       aResponse.setResponseValue("mail_to",aRequest.getParameter("mail_to"));
     if (ValidationHelper.testFieldEntered(aRequest, "mail_from", "validationerror.missing", aValidationErrors))
@@ -180,23 +180,23 @@ public class MirBasicEmailArticleHandler implements SessionHandler {
     }
     else {
       try {
-       ModuleContent contentModule = new ModuleContent(DatabaseContent.getInstance());
+       ModuleContent contentModule = new ModuleContent();
        EntityContent contentEnt = (EntityContent) contentModule.getById(aid);
-       
+
        Map articleData = new HashMap();
        articleData.put("article", MirGlobal.localizer().dataModel().adapterModel().makeEntityAdapter("content", contentEnt));
        articleData.put("languagecode", language);
        Map responseData = GeneratorHelper.makeBasicGenerationData(new Locale[] {new Locale(language,""),new Locale(configuration.getString("Mir.Admin.FallbackLanguage", "en"), "")},"bundles.open","bundles.open");
        responseData.put("data",articleData);
-       
+
        String emailAnArticleTemplate = configuration.getString("Localizer.OpenSession.email.MailTemplate");
-       
+
        Generator generator = MirGlobal.localizer().generators().makeOpenPostingGeneratorLibrary().makeGenerator(emailAnArticleTemplate);
-       
+
        StringWriter theEmailStringWriter = new StringWriter();
        PrintWriter theEmailPrintWriter = new PrintWriter(theEmailStringWriter);
        generator.generate(theEmailPrintWriter, responseData, logger);
-       
+
        theEmailStringWriter.close();
 
        theText = theEmailStringWriter.toString();
@@ -211,44 +211,45 @@ public class MirBasicEmailArticleHandler implements SessionHandler {
   }
 
   protected String getExtraEmailHeaders(Request aRequest,String to,String from) throws SessionExc {
-    
+
     String headers = "To: " + to + "\nReply-To: "+ from+"\n";;
     if (configuration.getString("Localizer.OpenSession.email.includeSenderIP","no").equals("yes"))
       headers= headers+"X-Originating-IP: "+ ((HTTPRequestAdapter)aRequest).getRequest().getRemoteAddr() + "\n";
-    
+
     return headers;
   }
 
   protected String interpolateComment(String emailText,String comment,String from_name,String language) throws SessionExc{
-      if (comment != null) {
-       MessageResources messages = MessageResources.getMessageResources("bundles.open");
-       String commentTextToInsert=messages.getMessage(new Locale(language,""),"email.comment.intro", from_name)+"\n";
-       
-       try {
-         emailText=StringRoutines.performRegularExpressionReplacement(emailText,"!COMMENT!",commentTextToInsert);
-       }
-       catch (Throwable e){
-         throw new SessionExc("Problem doing regular expression replacement :" + e.toString());
-       }
+    if (comment != null) {
+      String commentTextToInsert =
+          MirGlobal.getBundleFactory().getBundle("etc/bundles/open", new String[] { language }).
+            getValue("email.comment.intro" , Collections.singletonList(from_name)) + "\n";
+
+      try {
+        emailText = StringRoutines.performRegularExpressionReplacement(emailText, "!COMMENT!", commentTextToInsert);
       }
-      else{
-       try {
-       emailText=StringRoutines.performRegularExpressionReplacement(emailText,"!COMMENT!","");
-       }
-       catch (Throwable e){
-         throw new SessionExc("Problem doing regular expression replacement " + e.toString());
-       }
+      catch (Throwable e) {
+        throw new SessionExc("Problem doing regular expression replacement :" + e.toString());
+      }
+    }
+    else {
+      try {
+        emailText = StringRoutines.performRegularExpressionReplacement(emailText, "!COMMENT!", "");
+      }
+      catch (Throwable e) {
+        throw new SessionExc("Problem doing regular expression replacement " + e.toString());
       }
-      return emailText;
+    }
+    return emailText;
   }
-  
+
   protected boolean doTheSMTP(String aMessage,String aTo,String aFrom) throws SessionExc{
    SMTPClient client=new SMTPClient();
    try {
      int reply;
      client.connect(configuration.getString("ServletModule.OpenIndy.SMTPServer"));
      reply = client.getReplyCode();
-     
+
      if (!SMTPReply.isPositiveCompletion(reply)) {
        client.disconnect();
        throw new SessionExc("SMTP server refused connection.");
@@ -270,47 +271,46 @@ public class MirBasicEmailArticleHandler implements SessionHandler {
        }
       }
       throw new SessionExc(e.getMessage());
-   } 
+   }
   }
-  
+
   protected boolean sendMail(Request aRequest,Session aSession,Response aResponse) throws SessionExc,SessionFailure {
-    String aid=aRequest.getParameter("mail_aid");
     String to=aRequest.getParameter("mail_to");
     String from=aRequest.getParameter("mail_from");
     String from_name=aRequest.getParameter("mail_from_name");
     String language=aRequest.getParameter("mail_language");
     String comment=aRequest.getParameter("mail_comment");
-    
+
     String theEmailText=getEmailText((String) aSession.getAttribute("email.aid"),language);
     String headers=getExtraEmailHeaders(aRequest,to,from);
     theEmailText=interpolateComment(theEmailText,comment,from_name,language);
-    String message=headers+"\n"+theEmailText;
+    String message=headers+theEmailText;  // the space between headers and content is in the template
 
     return doTheSMTP(message,to,from);
-       
+
   }
 
 
   protected void subsequentRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     List validationErrors = new Vector();
     if (shouldSendMail(aRequest,aSession,aResponse,validationErrors)){
-      
+
       sendMail(aRequest,aSession,aResponse);
       aResponse.setResponseGenerator(configuration.getString("Localizer.OpenSession.email.DoneTemplate"));
     }
     else {
-      aResponse.setResponseValue("mail_comment",aRequest.getParameter("mail_comment"));  //everything else is required 
+      aResponse.setResponseValue("mail_comment",aRequest.getParameter("mail_comment"));  //everything else is required
       aResponse.setResponseValue("errors",validationErrors);
       aResponse.setResponseGenerator(configuration.getString("Localizer.OpenSession.email.PrepareTemplate"));
     }
-    
+
   }
-  
+
       /*
       String mail_language = aRequest.getParameter("mail_language");
       if (mail_language == null)
-       mail_language = configuration.getString("Mir.Login.DefaultLanguage", "en");     
-       
+       mail_language = configuration.getString("Mir.Login.DefaultLanguage", "en");
+
       aResponse.setResponseValue("mail_language",mail_language);
       */
 
index d9b4407..05e43a2 100755 (executable)
@@ -55,36 +55,37 @@ public class MirBasicGeneratorLocalizer implements MirGeneratorLocalizer {
   protected void buildRepository(GeneratorLibraryRepository aRepository) {
     aRepository.registerLibraryFactory(
         "freemarker",
-        new FreemarkerGenerator.FreemarkerGeneratorLibraryFactory(MirGlobal.config().getString("Home") ) );
+        new FreemarkerGenerator.FreemarkerGeneratorLibraryFactory(
+            MirGlobal.config().getHome()));
     aRepository.registerLibraryFactory(
         "velocity",
-        new VelocityGenerator.VelocityGeneratorLibraryFactory(MirGlobal.config().getString("Home") ) );
+        new VelocityGenerator.VelocityGeneratorLibraryFactory(MirGlobal.config().getHome() ) );
     aRepository.registerLibraryFactory(
         "tal",
-        new TALGenerator.TALGeneratorLibraryFactory(MirGlobal.config().getString("Home") ) );
+        new TALGenerator.TALGeneratorLibraryFactory(MirGlobal.config().getHome() ) );
   }
 
-  public Generator.GeneratorLibrary makeProducerGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
+  public Generator.Library makeProducerGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
     try {
-      return repository.constructCompositeLibrary(MirGlobal.config().getString("Mir.Localizer.Producer.GeneratorLibrary"));
+      return repository.constructCompositeLibrary(MirGlobal.config().getStringArray("Mir.Localizer.Producer.GeneratorLibrary"));
     }
     catch (Throwable t) {
       throw new MirLocalizerFailure(t);
     }
   };
 
-  public Generator.GeneratorLibrary makeAdminGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
+  public Generator.Library makeAdminGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
     try {
-      return repository.constructCompositeLibrary(MirGlobal.config().getString("Mir.Localizer.Admin.GeneratorLibrary"));
+      return repository.constructCompositeLibrary(MirGlobal.config().getStringArray("Mir.Localizer.Admin.GeneratorLibrary"));
     }
     catch (Throwable t) {
       throw new MirLocalizerFailure(t);
     }
   };
 
-  public Generator.GeneratorLibrary makeOpenPostingGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
+  public Generator.Library makeOpenPostingGeneratorLibrary() throws MirLocalizerExc, MirLocalizerFailure {
     try {
-      return repository.constructCompositeLibrary(MirGlobal.config().getString("Mir.Localizer.OpenPosting.GeneratorLibrary"));
+      return repository.constructCompositeLibrary(MirGlobal.config().getStringArray("Mir.Localizer.OpenPosting.GeneratorLibrary"));
     }
     catch (Throwable t) {
       throw new MirLocalizerFailure(t);
index e3c7747..b3d33ef 100755 (executable)
  */
 package mircoders.localizer.basic;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Vector;
-import java.util.Iterator;
-
 import mir.config.MirPropertiesConfiguration;
 import mir.log.LoggerWrapper;
 import mir.session.Request;
@@ -49,6 +42,9 @@ import mircoders.localizer.MirAntiAbuseFilterType;
 import mircoders.localizer.MirLocalizerExc;
 import mircoders.localizer.MirLocalizerFailure;
 import mircoders.localizer.MirOpenPostingLocalizer;
+import mircoders.localizer.basic.filters.ThrottleFilter;
+
+import java.util.*;
 
 public class MirBasicOpenPostingLocalizer implements MirOpenPostingLocalizer {
   private List afterContentProducerTasks;
@@ -88,16 +84,19 @@ public class MirBasicOpenPostingLocalizer implements MirOpenPostingLocalizer {
     addSimpleAntiAbuseFilterType(new MirBasicAntiAbuseFilterTypes.RegularExpressionFilter("useragent", false, false,
         MirBasicAntiAbuseFilterTypes.RegularExpressionFilter.REQUEST_HEADERS, new String[] {"User-Agent"}));
     addSimpleAntiAbuseFilterType(new MirBasicAntiAbuseFilterTypes.IPFilter("ip"));
+    addSimpleAntiAbuseFilterType(new MirBasicAntiAbuseFilterTypes.RegularExpressionFilter("hostname", false, false,
+        MirBasicAntiAbuseFilterTypes.RegularExpressionFilter.REQUEST_HEADERS, new String[] {"hostname"}));
+    addSimpleAntiAbuseFilterType(new ThrottleFilter("throttle", 60*60*1000));
   }
 
   public SessionHandler getOpenSessionHandler(String aSessionType) throws MirLocalizerExc, MirLocalizerFailure  {
-/*    if (aSessionType!=null && aSessionType.equals("email"))
+    if (aSessionType!=null && aSessionType.equals("email"))
       return new MirBasicEmailArticleHandler();
-*/
+
     if (aSessionType!=null && aSessionType.equals("comment"))
-      return new MirBasicCommentPostingHandler();
+      return new MirBasicCommentPostingHandler(configuration.getBoolean("Localizer.OpenSession.PersistentUploadedFiles"));
 
-    return new MirBasicArticlePostingHandler();
+    return new MirBasicArticlePostingHandler(configuration.getBoolean("Localizer.OpenSession.PersistentUploadedFiles"));
   }
 
   public SessionHandler getOpenSessionHandler(Request aRequest, Session aSession) throws MirLocalizerExc, MirLocalizerFailure {
@@ -116,7 +115,7 @@ public class MirBasicOpenPostingLocalizer implements MirOpenPostingLocalizer {
       ProducerEngine.ProducerTask task = (ProducerEngine.ProducerTask) i.next();
 
       try {
-        MirGlobal.producerEngine().addTask(task);
+        MirGlobal.getProducerEngine().addTask(task);
       }
       catch (Throwable t) {
         logger.error("Error adding content task "+task.getProducer()+"::"+task.getVerb()+": " + t.toString());
@@ -139,7 +138,7 @@ public class MirBasicOpenPostingLocalizer implements MirOpenPostingLocalizer {
       ProducerEngine.ProducerTask task = (ProducerEngine.ProducerTask) i.next();
 
       try {
-        MirGlobal.producerEngine().addTask(task);
+        MirGlobal.getProducerEngine().addTask(task);
       }
       catch (Throwable t) {
         logger.error("Error adding comment task "+task.getProducer()+"::"+task.getVerb()+": " + t.toString());
index 786fd62..d762c0d 100755 (executable)
  */
 package mircoders.localizer.basic;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Vector;
-
 import mir.config.MirPropertiesConfiguration;
 import mir.log.LoggerWrapper;
-import mir.session.Request;
-import mir.session.Response;
-import mir.session.Session;
-import mir.session.SessionExc;
-import mir.session.SessionFailure;
-import mir.session.SessionHandler;
-import mir.session.UploadedFile;
-import mir.session.ValidationError;
+import mir.session.*;
 import mir.storage.StorageObject;
 import mir.util.ExceptionFunctions;
+import mir.util.FileFunctions;
 import mircoders.global.MirGlobal;
 import mircoders.module.ModuleMediaType;
+import mircoders.media.UnsupportedMediaTypeExc;
+
+import java.io.*;
+import java.util.*;
 
 /**
- *
- * <p>Title: Experimental session handler for comment postings </p>
- * <p>Description: </p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: </p>
- * @author not attributable
- * @version 1.0
+ * Extensible handler for open postings.
+ * Behaviour can be altered by overriding methods.
  */
-
 public abstract class MirBasicPostingSessionHandler implements SessionHandler {
-  protected LoggerWrapper logger;
-  protected MirPropertiesConfiguration configuration;
+  protected static LoggerWrapper logger = new LoggerWrapper("Localizer.OpenPosting");
+  protected MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();;
+
+  /** Previously uploaded files */
+  protected List attachments;
+  /** counter to generate unique field names for uploaded files */
+  protected int uploadedFileIndex = 0;
 
   private String normalResponseGenerator;
   private String dupeResponseGenerator;
   private String unsupportedMediaTypeResponseGenerator;
   private String finalResponseGenerator;
 
+  private boolean persistentUploadedFiles;
 
-  public MirBasicPostingSessionHandler() {
-    logger = new LoggerWrapper("Localizer.OpenPosting");
-    try {
-      configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (Throwable t) {
-      logger.fatal("Cannot load configuration: " + t.toString());
-
-      throw new RuntimeException("Cannot load configuration: " + t.toString());
-    }
+  public MirBasicPostingSessionHandler(boolean aPersistentUploadedFiles) {
+    attachments = new ArrayList();
+    persistentUploadedFiles = aPersistentUploadedFiles;
   }
 
   protected void setNormalResponseGenerator(String aGenerator) {
     normalResponseGenerator = aGenerator;
   }
 
-  protected void setResponseGenerators(String aNormalResponseGenerator, String aDupeResponseGenerator,
-        String anUnsupportedMediaTypeResponseGenerator, String aFinalResponseGenerator) {
+  protected void setResponseGenerators(String aNormalResponseGenerator,
+        String aDupeResponseGenerator, String anUnsupportedMediaTypeResponseGenerator,
+        String aFinalResponseGenerator) {
     setNormalResponseGenerator(aNormalResponseGenerator);
     dupeResponseGenerator = aDupeResponseGenerator;
     unsupportedMediaTypeResponseGenerator = anUnsupportedMediaTypeResponseGenerator;
@@ -117,10 +102,30 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
     makeInitialResponse(aRequest, aSession, aResponse);
   }
 
+  protected void processAttachments(Request aRequest, Session aSession, Response aResponse) {
+    Iterator i = attachments.iterator();
+    while (i.hasNext()) {
+      Attachment attachment = (Attachment) i.next();
+      try{
+        processAttachment(aRequest, aSession, attachment);
+      }
+      catch (Throwable t) {
+        try {
+          processAttachmentError(aRequest, aSession, attachment, t);
+        }
+        catch (Throwable u) {
+        }
+      }
+    }
+  }
+
   public void subsequentRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     try {
       try {
-        List validationErrors = new Vector();
+        List validationErrors = new ArrayList();
+
+        preprocessPreviousAttachments(aRequest, aSession);
+        preProcessNewAttachments(aRequest, aSession);
 
         if (!shouldProcessRequest(aRequest, aSession, validationErrors)) {
           initializeResponseData(aRequest, aSession, aResponse);
@@ -128,10 +133,8 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
         }
         else {
           preProcessRequest(aRequest, aSession);
-          Iterator i = aRequest.getUploadedFiles().iterator();
-          while (i.hasNext()) {
-            processUploadedFile(aRequest, aSession, (UploadedFile) i.next());
-          }
+
+          processAttachments(aRequest, aSession, aResponse);
           postProcessRequest(aRequest, aSession);
           initializeResponseData(aRequest, aSession, aResponse);
           makeFinalResponse(aRequest, aSession, aResponse);
@@ -151,6 +154,11 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
     }
   }
 
+  /**
+   * Initializes a session.
+   * This may happen in the case of a new session being initiated, but also
+   * when an older session gets re-initiated after a session timeout.
+   */
   protected void initializeSession(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
     if (MirGlobal.abuse().getOpenPostingPassword()) {
       String password = (String) aSession.getAttribute("password");
@@ -163,29 +171,30 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
       aSession.deleteAttribute("password");
     }
 
-    logger.debug("referrer = " + aRequest.getHeader("Referer"));
-
     aSession.setAttribute("referer", aRequest.getHeader("Referer"));
   }
 
+  /**
+   * Called every time a response is being prepared.
+   * This may be at the initial response, or on a subsequent one.
+   */
   protected void initializeResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
     int nrMediaItems = configuration.getInt("ServletModule.OpenIndy.DefaultMediaUploadItems", 5);
 
     if (aSession.getAttribute("nrmediaitems")!=null) {
       nrMediaItems = ((Integer) aSession.getAttribute("nrmediaitems")).intValue();
     }
+
     try {
       nrMediaItems = Math.min(configuration.getInt("ServletModule.OpenIndy.MaxMediaUploadItems"), Integer.parseInt(aRequest.getParameter("nrmediaitems")));
     }
     catch (Throwable t) {
     }
-    aSession.setAttribute("nrmediaitems", new Integer(nrMediaItems));
 
-    List mediaItems = new Vector();
-    int i=0;
+    aSession.setAttribute("nrmediaitems", new Integer(nrMediaItems));
 
-    while (i<nrMediaItems) {
-      i++;
+    List mediaItems = new ArrayList();
+    for (int i=1; i<=nrMediaItems; i++) {
       mediaItems.add(new Integer(i));
     }
 
@@ -194,6 +203,143 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
     aResponse.setResponseValue("password", aSession.getAttribute("password"));
     aResponse.setResponseValue("referer", aSession.getAttribute("referer"));
     aResponse.setResponseValue("errors", null);
+
+    if (configuration.getBoolean("Localizer.OpenSession.AllowFTPUploads", false)) {
+      aResponse.setResponseValue("ftpfiles",
+          FileFunctions.getDirectoryContentsAsList(configuration.getFile("Localizer.OpenSession.FTPDirectory"),
+              new FilenameFilter() {
+                public boolean accept(File aDir, String aName) {
+                  return !(new File(aDir, aName).isDirectory());
+                }
+          }));
+    }
+    else {
+      aResponse.setResponseValue("ftpfiles", null);
+    }
+
+    initializeAttachmentResponseData(aRequest, aSession, aResponse);
+  }
+
+  /**
+   * Process possible changes to previously uploaded files
+   */
+  protected void initializeAttachmentResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
+    List result = new ArrayList();
+    if (persistentUploadedFiles) {
+      Iterator i = attachments.iterator();
+      while (i.hasNext()) {
+        Attachment attachment = (Attachment) i.next();
+        Map attachmentData = new HashMap();
+        attachmentData.putAll(attachment.getAllAttributes());
+        attachmentData.put("fieldname", attachment.getFieldName());
+        attachmentData.put("filename", attachment.getFileName());
+        result.add(attachmentData);
+      }
+    }
+
+    aResponse.setResponseValue("attachments", result);
+  }
+
+  /**
+   * Process possible changes to previously uploaded files
+   */
+  protected void preprocessPreviousAttachments(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
+    synchronized (attachments) {
+      List previouslyUploadedFiles = new ArrayList(attachments);
+      attachments.clear();
+
+      if (persistentUploadedFiles) {
+        Iterator i = previouslyUploadedFiles.iterator();
+        while (i.hasNext()) {
+          Attachment uploadedFile = (Attachment) i.next();
+          if (!(aRequest.getParameter(uploadedFile.getFieldName()+"_cancel")!=null)) {
+            addAttachment(aRequest, aSession, uploadedFile, uploadedFile.getFieldName());
+          }
+        }
+      }
+    }
+  }
+
+  protected void addAttachment(Request aRequest, Session aSession, Attachment anAttachment, String aFieldName) throws SessionExc, SessionFailure {
+    List parameters = aRequest.getPrefixedParameterNames(aFieldName+"_");
+    Iterator j = parameters.iterator();
+    while (j.hasNext()) {
+      String parameter = ((String) j.next());
+      anAttachment.setAttribute(
+          parameter.substring(aFieldName.length()+1),
+          aRequest.getParameter(parameter));
+    }
+    attachments.add(anAttachment);
+  }
+
+  public void preprocessNewAttachment(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {
+      Attachment uploadedFile =
+          new Attachment(aFile, aFile.getFileName(), "attachment"+ ++uploadedFileIndex, aFile.getContentType());
+
+      addAttachment(aRequest, aSession, uploadedFile, aFile.getFieldName());
+  }
+
+
+  /**
+   * Process newly uploaded files
+   */
+  protected void preProcessNewAttachments(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
+    Iterator i = aRequest.getUploadedFiles().iterator();
+    while (i.hasNext()) {
+      preprocessNewAttachment(aRequest, aSession, (UploadedFile) i.next());
+    }
+
+    if (configuration.getBoolean("Localizer.OpenSession.AllowFTPUploads", false)) {
+      File FTPDirectory = configuration.getFile("Localizer.OpenSession.FTPDirectory");
+
+      List ftpUploads = aRequest.getPrefixedParameterNames("ftpupload");
+      i = ftpUploads.iterator();
+      while (i.hasNext()) {
+        final String fieldName = (String) i.next();
+
+        if (fieldName.indexOf("_")<0) {
+          final String fileName = aRequest.getParameter(fieldName);
+
+          if (fileName!=null && fileName.trim().length()>0) {
+            final File sourceFile = new File(FTPDirectory, fileName);
+
+            if (sourceFile.getParentFile().equals(FTPDirectory)) {
+              preprocessNewAttachment(aRequest, aSession, new UploadedFile() {
+                public void writeToFile(File aFile) throws SessionFailure {
+                  try {
+                    FileFunctions.move(sourceFile, aFile);
+                  }
+                  catch (IOException e) {
+                    throw new SessionFailure(e);
+                  }
+                }
+
+                public InputStream getInputStream() throws SessionFailure {
+                  try {
+                    return new FileInputStream(sourceFile);
+                  }
+                  catch (IOException e) {
+                    throw new SessionFailure(e);
+                  }
+                }
+
+                public String getFileName() {
+                  return fileName;
+                }
+
+                public String getFieldName() {
+                  return fieldName;
+                }
+
+                public String getContentType() {
+                  return null;
+                }
+              });
+            }
+          }
+        }
+      }
+    }
   }
 
   protected void makeInitialResponse(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
@@ -210,18 +356,19 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
   };
 
   protected void makeErrorResponse(Request aRequest, Session aSession, Response aResponse, Throwable anError) throws SessionExc, SessionFailure {
-    anError.printStackTrace();
     Throwable rootCause = ExceptionFunctions.traceCauseException(anError);
 
     if (rootCause instanceof DuplicatePostingExc)
       aResponse.setResponseGenerator(dupeResponseGenerator);
-    if (rootCause instanceof ModuleMediaType.UnsupportedMimeTypeExc) {
-      aResponse.setResponseValue("mimetype", ((ModuleMediaType.UnsupportedMimeTypeExc) rootCause).getMimeType());
+    if (rootCause instanceof UnsupportedMediaTypeExc) {
+      aResponse.setResponseValue("mimetype", ((UnsupportedMediaTypeExc) rootCause).getMimeType());
       aResponse.setResponseGenerator(unsupportedMediaTypeResponseGenerator);
     }
     else {
-      aResponse.setResponseValue("errorstring", anError.getMessage());
-      aResponse.setResponseGenerator(configuration.getString("Localizer.OpenSession.ErrorTemplate"));
+      List errors = new ArrayList();
+      errors.add(new ValidationError("", "general.unexpectederror",
+          new Object[] {anError.getMessage()}));
+      makeResponse(aRequest, aSession, aResponse, errors);
     }
   };
 
@@ -229,13 +376,23 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
     aResponse.setResponseGenerator(configuration.getString("ServletModule.OpenIndy.PostingDisabledTemplate"));
   }
 
+  /**
+   *
+   */
   protected void preProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
   };
-  public void processUploadedFile(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {
+  public void processAttachment(Request aRequest, Session aSession, Attachment aFile) throws SessionExc, SessionFailure {
+  };
+  public void processAttachmentError(Request aRequest, Session aSession, Attachment aFile, Throwable anError) {
   };
   protected void postProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
   };
 
+  /**
+   * Determine whether the request shoudl be processed: that is, the validate,
+   * preprocess, postprocess methods should be called to perform validations,
+   * store data, etc
+   */
   protected boolean shouldProcessRequest(Request aRequest, Session aSession, List aValidationErrors) throws SessionExc, SessionFailure {
     if (aRequest.getParameter("post")==null)
       return false;
@@ -245,6 +402,13 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
     }
   }
 
+  /**
+   * Method used to validate user input.
+   * Multiple {@link ValidationError}s may be added to the
+   * <code>aResults</code> parameter.
+   * The request is considered validated if, after calling this method,
+   * <code>aResults</code> is empty.
+   */
   protected void validate(List aResults, Request aRequest, Session aSession) throws SessionExc, SessionFailure {
     String password = (String) aSession.getAttribute("password");
 
@@ -263,7 +427,6 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
    *
    * @return a password, to be used once
    */
-
   protected String generateOnetimePassword() {
     Random r = new Random();
     int random = r.nextInt();
@@ -279,20 +442,14 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
     return returnString.substring(5);
   }
 
-
   /**
-   *
-   * @param aRequest
-   * @param aStorage
-   * @return
-   * @throws SessionExc
-   * @throws SessionFailure
+   * Method to filter the attributes and their values of a request
+   * based on the fields of a storage object.
    */
-
-  protected static final Map getIntersectingValues(Request aRequest, StorageObject aStorage) throws SessionExc, SessionFailure {
+  protected static final Map getIntersectingValues(Request aRequest, StorageObject aStorage) throws SessionFailure {
     Map result = new HashMap();
 
-    Iterator i = aStorage.getFields().iterator();
+    Iterator i = aStorage.getFieldNames().iterator();
 
     while (i.hasNext()) {
       String fieldName = (String) i.next();
@@ -304,10 +461,64 @@ public abstract class MirBasicPostingSessionHandler implements SessionHandler {
     return result;
   }
 
+  /**
+   * Exception to be thrown when an article or comment was already posted
+   */
   protected static class DuplicatePostingExc extends SessionExc {
     public DuplicatePostingExc(String aMessage) {
       super(aMessage);
     }
   }
 
+  /**
+   * A file that has been attached to a session
+   */
+  protected static class Attachment implements UploadedFile {
+    private UploadedFile uploadedFile;
+    private String filename;
+    private String fieldName;
+    private String contentType;
+    private Map attributes;
+
+    public Attachment(UploadedFile anUploadedFile, String aFilename, String aFieldName, String aContentType) {
+      attributes = new HashMap();
+      filename = aFilename;
+      fieldName = aFieldName;
+      contentType = aContentType;
+      uploadedFile = anUploadedFile;
+    }
+
+    public void writeToFile(File aFile) throws SessionExc, SessionFailure {
+      uploadedFile.writeToFile(aFile);
+    }
+
+    public InputStream getInputStream() throws SessionExc, SessionFailure {
+      return uploadedFile.getInputStream();
+    }
+
+    public String getFileName() {
+      return filename;
+    }
+
+    public String getFieldName() {
+      return fieldName;
+    }
+
+    public String getContentType() {
+      return contentType;
+    }
+
+    public String getAttribute(String anAttribute) {
+      return (String) attributes.get(anAttribute);
+    }
+
+    public void setAttribute(String anAttribute, String aValue) {
+      attributes.put(anAttribute, aValue);
+    }
+
+    public Map getAllAttributes() {
+      return Collections.unmodifiableMap(attributes);
+    }
+  }
 }
+
index c946124..8b96748 100755 (executable)
  */
 package mircoders.localizer.basic;
 
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
 import mir.config.MirPropertiesConfiguration;
 import mir.entity.adapter.EntityAdapter;
 import mir.entity.adapter.EntityIteratorAdapter;
+import mir.generator.Generator;
+import mir.generator.GeneratorExc;
+import mir.generator.GeneratorFailure;
 import mir.log.LoggerWrapper;
 import mir.misc.StringUtil;
-import mir.util.GeneratorDateTimeFunctions;
-import mir.util.GeneratorExpressionFunctions;
-import mir.util.GeneratorFormatAdapters;
-import mir.util.GeneratorHTMLFunctions;
-import mir.util.GeneratorIntegerFunctions;
-import mir.util.GeneratorListFunctions;
-import mir.util.GeneratorRegularExpressionFunctions;
-import mir.util.GeneratorStringFunctions;
+import mir.util.*;
+import mir.util.generator.ReflectionGeneratorFunctionsAdapter;
 import mircoders.global.MirGlobal;
 import mircoders.localizer.MirLocalizerExc;
 import mircoders.localizer.MirLocalizerFailure;
 import mircoders.localizer.MirProducerAssistantLocalizer;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.tidy.Tidy;
+import org.w3c.tidy.Configuration;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantLocalizer {
   protected LoggerWrapper logger;
@@ -60,7 +67,6 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL
       Iterator i;
 
       Map configMap = new HashMap();
-      Map utilityMap = new HashMap();
 
       logger = new LoggerWrapper("Localizer.ProducerAssistant");
 
@@ -82,27 +88,9 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL
 // "new":
       configMap.putAll(MirPropertiesConfiguration.instance().allSettings());
 
-      utilityMap.put("compressWhitespace", new freemarker.template.utility.CompressWhitespace());
-      utilityMap.put("encodeHTML", new GeneratorHTMLFunctions.encodeHTMLGeneratorFunction());
-      utilityMap.put("prettyEncodeHTML", new GeneratorHTMLFunctions.prettyEncodeHTMLGeneratorFunction());
-      utilityMap.put("encodeXML", new GeneratorHTMLFunctions.encodeXMLGeneratorFunction());
-      utilityMap.put("encodeURI", new GeneratorHTMLFunctions.encodeURIGeneratorFunction());
-      utilityMap.put("subString", new GeneratorStringFunctions.subStringFunction());
-      utilityMap.put("subList", new GeneratorListFunctions.subListFunction());
-      utilityMap.put("listSize", new GeneratorListFunctions.listSizeFunction());
-      utilityMap.put("isOdd", new GeneratorIntegerFunctions.isOddFunction());
-      utilityMap.put("increment", new GeneratorIntegerFunctions.incrementFunction());
-      utilityMap.put("evaluate", new GeneratorExpressionFunctions.evaluateExpressionFunction());
-      utilityMap.put("constructString", new GeneratorStringFunctions.constructStructuredStringFunction());
-      utilityMap.put("parseStructuredString", new GeneratorStringFunctions.structuredStringParserFunction());
-      utilityMap.put("escapeJDBCString", new GeneratorStringFunctions.jdbcStringEscapeFunction());
-      utilityMap.put("regexpreplace", new GeneratorRegularExpressionFunctions.regularExpressionReplaceFunction());
-      utilityMap.put("regexpmatch", new GeneratorRegularExpressionFunctions.regularExpressionMatchFunction());
-      utilityMap.put("datetime", new GeneratorDateTimeFunctions.DateTimeFunctions(
-          MirPropertiesConfiguration.instance().getString("Mir.DefaultTimezone")));
-
       aValueSet.put("config", configMap);
-      aValueSet.put("utility", utilityMap);
+
+      aValueSet.put("utility", new Utility()); 
 
       aValueSet.put("languages",
         new EntityIteratorAdapter("", "", 20, MirGlobal.localizer().dataModel().adapterModel(), "language"));
@@ -133,6 +121,7 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL
         commentStatusMap.put(commentStatus.get("name"), commentStatus.get("id"));
       }
       aValueSet.put("commentstatus", commentStatusMap);
+      aValueSet.put("languageCodeToId", new getLanguageIdFunction());
     }
     catch (Throwable t) {
       logger.error("initializeGenerationValueSet: Exception while collecting comment statuses" + t.getMessage());
@@ -140,6 +129,52 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL
     }
 
   };
+  public static class getLanguageIdFunction implements Generator.Function {
+    private Map languageCodeToId;
+    private String otherLanguageId;
+    private LoggerWrapper logger = new LoggerWrapper("Localizer.Earth.getLanguageIdFunction");
+
+    public getLanguageIdFunction() throws MirLocalizerFailure {
+      try {
+        otherLanguageId = "";
+        languageCodeToId = new HashMap();
+
+        Iterator i = new EntityIteratorAdapter("", "", 20, MirGlobal.localizer().dataModel().adapterModel(), "language");
+        while (i.hasNext()) {
+          EntityAdapter language = (EntityAdapter) i.next();
+          if (language.get("code").equals("ot"))
+            otherLanguageId = (String) language.get("id");
+
+          languageCodeToId.put(language.get("code"), language.get("id"));
+        }
+      }
+      catch (Throwable t) {
+        logger.error(t.toString());
+
+        throw new MirLocalizerFailure(t);
+      }
+    }
+
+    public Object perform(List aParameters) throws GeneratorExc, GeneratorFailure {
+      try {
+        if (aParameters.size() != 1)
+          throw new GeneratorExc("getLanguageIdFunction: 1 parameter expected: language-code");
+
+        String result = (String) languageCodeToId.get(aParameters.get(0));
+        if (result == null)
+          result = otherLanguageId;
+
+        return result;
+      }
+      catch (GeneratorExc e) {
+        throw e;
+      }
+      catch (Throwable t) {
+        throw new GeneratorFailure("getLanguageIdFunction: " + t.getMessage(), t);
+      }
+    };
+  }
+
 
   public String filterNonHTMLText(String aText) {
 
@@ -162,8 +197,139 @@ public class MirBasicProducerAssistantLocalizer implements MirProducerAssistantL
       throw new RuntimeException(t.toString());
     }
   }
-
   public String filterHTMLText(String aText) {
-    return StringUtil.deleteForbiddenTags(aText);
+    try {
+      StringWriter out = new StringWriter();
+      Tidy tidy = new Tidy();
+      ByteArrayInputStream in = new ByteArrayInputStream(aText.getBytes("UTF8"));
+      tidy.setMakeClean(true);
+      tidy.setCharEncoding(Configuration.UTF8);
+      tidy.setErrout(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+      print(tidy.parseDOM(in, null), out);
+      
+      return out.toString();
+    }
+    catch (IOException e) {
+      return e.getMessage();
+    }
+  }
+
+  private boolean checkAttr(String attrName) {
+    if (attrName.equals("onLoad") || attrName.equals("onClick") || attrName.equals("onFocus") || attrName.equals("onBlur") || attrName.equals("onMouseOver") || attrName.equals("onMouseOut") || attrName.equals("style") || attrName.equals("STYLE") || attrName.equals("height") || attrName.equals("width") || attrName.equals("HEIGHT") || attrName.equals("WIDTH"))
+      return false;
+    else
+      return true;
+
+  }
+
+  private boolean checkNode(String nodeName) {
+    if (nodeName.equals("a") ||
+        nodeName.equals("img") ||
+        nodeName.equals("h1") ||
+        nodeName.equals("h2") ||
+        nodeName.equals("h3") ||
+        nodeName.equals("h4") ||
+        nodeName.equals("h5") ||
+        nodeName.equals("h6") ||
+        nodeName.equals("br") ||
+        nodeName.equals("form") ||
+        nodeName.equals("input") ||
+        nodeName.equals("hr") ||
+        nodeName.equals("strong") ||
+        nodeName.equals("font") ||
+        nodeName.equals("b") ||
+        nodeName.equals("i") ||
+        nodeName.equals("em") ||
+        nodeName.equals("p") ||
+        nodeName.equals("table") ||
+        nodeName.equals("tr") ||
+        nodeName.equals("td") ||
+        nodeName.equals("th") ||
+        nodeName.equals("ul") ||
+        nodeName.equals("ol") ||
+        nodeName.equals("li")
+    ) {
+      return true;
+    } else {
+
+      return false;
+    }
+  }
+
+  private void print(Node node, StringWriter out) throws IOException {
+    if (node == null) {
+      return;
+    }
+    int type = node.getNodeType();
+    boolean canOutput = checkNode(node.getNodeName());
+
+    switch (type) {
+
+      case Node.DOCUMENT_NODE:
+
+        print(((Document) node).getDocumentElement(), out);
+        out.flush();
+        break;
+
+      case Node.ELEMENT_NODE:
+        if (canOutput) {
+          out.write('<');
+
+          out.write(node.getNodeName());
+          NamedNodeMap attrs = node.getAttributes();
+
+          for (int i = 0; i < attrs.getLength(); i++) {
+            String attrName = attrs.item(i).getNodeName();
+            if (checkAttr(attrName)) {
+              out.write(' ');
+              out.write(attrs.item(i).getNodeName());
+              out.write("=\"");
+
+              out.write(attrs.item(i).getNodeValue());
+              out.write('"');
+            }
+          }
+
+          if (node.getChildNodes()==null || node.getChildNodes().getLength()==0) {
+            out.write("/");
+          }
+          out.write('>');
+        }
+        NodeList children = node.getChildNodes();
+        if (children != null) {
+          int len = children.getLength();
+          for (int i = 0; i < len; i++) {
+            print(children.item(i), out);
+          }
+        }
+        break;
+
+      case Node.TEXT_NODE:
+        out.write(node.getNodeValue());
+        break;
+
+    }
+
+    if (type == Node.ELEMENT_NODE && canOutput && node.getChildNodes()!=null && node.getChildNodes().getLength()>0) {
+      out.write("</");
+      out.write(node.getNodeName());
+      out.write('>');
+    }
+
+    out.flush();
+  }
+
+  public static class Utility extends ReflectionGeneratorFunctionsAdapter {
+    public Utility () {
+      super(new MirBasicUtilityFunctions());
+    }
+    public Object getDatetime() {
+      return new GeneratorDateTimeFunctions.DateTimeFunctions(
+        MirPropertiesConfiguration.instance().getString("Mir.DefaultTimezone"));
+    }
+
+    public Object getCompressWhitespace() {
+      return new freemarker.template.utility.CompressWhitespace();
+    }
   }
 }
index 8b4f987..66d5596 100755 (executable)
@@ -40,11 +40,9 @@ import mir.entity.adapter.EntityAdapterModel;
 import mir.generator.Generator;
 import mir.generator.WriterEngine;
 import mir.log.LoggerWrapper;
-import mir.producer.ProducerFactory;
 import mir.producer.reader.DefaultProducerNodeBuilders;
 import mir.producer.reader.ProducerConfigReader;
 import mir.producer.reader.ProducerNodeBuilderLibrary;
-import mir.util.FileMonitor;
 import mir.util.StringRoutines;
 import mircoders.global.MirGlobal;
 import mircoders.global.ProducerEngine;
@@ -54,15 +52,11 @@ import mircoders.localizer.MirProducerLocalizer;
 import mircoders.producer.reader.SupplementalProducerNodeBuilders;
 
 public class MirBasicProducerLocalizer implements MirProducerLocalizer {
-  private List producerFactories;
-  private Map nameToFactory;
-
   private Map producerRecipes;
   private List producerRecipeNames;
 
-  protected FileMonitor fileMonitor;
   protected EntityAdapterModel model;
-  protected Generator.GeneratorLibrary generatorLibrary;
+  protected Generator.Library generatorLibrary;
   protected WriterEngine writerEngine;
 
   protected LoggerWrapper logger;
@@ -79,8 +73,10 @@ public class MirBasicProducerLocalizer implements MirProducerLocalizer {
         try {
           List parts = StringRoutines.separateString(recipes[i], "=");
           if (parts.size() == 2) {
-            producerRecipes.put(parts.get(0), ProducerEngine.ProducerTask.parseProducerTaskList( (String) parts.get(1)));
-            producerRecipeNames.add(parts.get(0));
+            String key = ((String) parts.get(0)).trim();
+            producerRecipes.put(key, ProducerEngine.ProducerTask.parseProducerTaskList(
+                ((String) parts.get(1)).trim()));
+            producerRecipeNames.add(key);
           }
           else {
             throw new Exception("'=' expected");
@@ -95,14 +91,15 @@ public class MirBasicProducerLocalizer implements MirProducerLocalizer {
       String allNewProducers = MirGlobal.config().getString("Mir.Localizer.Producer.AllNewProducers");
       if (allNewProducers!=null && allNewProducers.length()>0) {
         producerRecipes.put("allnew", ProducerEngine.ProducerTask.parseProducerTaskList(allNewProducers));
-        producerRecipeNames.add("allnew");
+
+        if (!producerRecipeNames.contains("allnew")) {
+          producerRecipeNames.add("allnew");
+        }
       }
 
-      producerFactories = new Vector();
       model = MirGlobal.localizer().dataModel().adapterModel();
       generatorLibrary = MirGlobal.localizer().generators().makeProducerGeneratorLibrary();
       writerEngine = MirGlobal.localizer().generators().makeWriterEngine();
-      nameToFactory = new HashMap();
     }
     catch (Throwable t) {
       logger.error("MirBasicProducerLocalizer(): Exception "+t.getMessage());
@@ -122,10 +119,11 @@ public class MirBasicProducerLocalizer implements MirProducerLocalizer {
         ProducerEngine.ProducerTask task = (ProducerEngine.ProducerTask) i.next();
 
         try {
-          MirGlobal.producerEngine().addTask(task);
+          MirGlobal.getProducerEngine().addTask(task);
         }
         catch (Throwable t) {
-          logger.error("Error recipe "+aName+" tasks "+task.getProducer()+"::"+task.getVerb()+": " + t.toString());
+          logger.error("Error recipe "+aName+" tasks "+
+              task.getProducer()+"::"+task.getVerb()+": " + t.toString());
         }
       }
     }
@@ -133,65 +131,46 @@ public class MirBasicProducerLocalizer implements MirProducerLocalizer {
       throw new MirLocalizerExc("Unknown recipe name: " + aName);
   }
 
-  public List factories() throws MirLocalizerExc {
-    if (fileMonitor==null || producerFactories == null || fileMonitor.hasChanged()) {
+  /**
+   * Loads factories from a file with a {@link ProducerConfigReader}
+   */
+  public List loadFactories() throws MirLocalizerExc {
       try {
-        List newProducers = new Vector();
-        FileMonitor newFileMonitor = new FileMonitor();
-        setupFactories(newProducers, newFileMonitor);
-
-        producerFactories = newProducers;
-        fileMonitor = newFileMonitor;
-        logger.info("MirBasicProducerLocalizer.factories(): successfully setup factories");
-
-        nameToFactory.clear();
-        Iterator i = producerFactories.iterator();
-        while (i.hasNext()) {
-          ProducerFactory factory = (ProducerFactory) i.next();
-          nameToFactory.put(factory.getName(), factory);
-        }
+        List producers = new Vector();
+        ProducerConfigReader reader;
+        ProducerNodeBuilderLibrary library = new ProducerNodeBuilderLibrary();
+        setupProducerNodeBuilderLibrary(library);
+        reader = new ProducerConfigReader();
+        File inputFile =
+            MirGlobal.config().getFile("Mir.Localizer.ProducerConfigFile");
+        reader.parse(inputFile, library, producers);
+
+        logger.info("MirBasicProducerLocalizer.loadFactories(): successfully loaded factories");
+
+        return producers;
       }
       catch (Throwable t) {
-        logger.error("MirBasicProducerLocalizer.factories(): Unable to setup factories: "+t.getMessage());
-        t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+        logger.error("MirBasicProducerLocalizer.loadFactories(): Unable to load factories: "+
+            t.getMessage());
+        throw new MirLocalizerFailure(t);
       }
-    }
-
-    return producerFactories;
   };
 
-  public ProducerFactory getFactoryForName(String aName) {
-    try {
-      factories();
-    }
-    catch (Throwable t) {
-    }
-
-    return (ProducerFactory) nameToFactory.get(aName);
-  }
-
+  /**
+   * Sets up a {@link ProducerNodeBuilderLibrary} for use by the producer
+   * definition reader. Can be overridden by subclasses to tweak the standard
+   * library.
+   */
   protected void setupProducerNodeBuilderLibrary(ProducerNodeBuilderLibrary aLibrary) throws MirLocalizerFailure {
     try {
       DefaultProducerNodeBuilders.registerBuilders(
           aLibrary, model, generatorLibrary, writerEngine,
-          MirGlobal.config().getString("Home"), MirGlobal.config().getString("Producer.StorageRoot"));
-      SupplementalProducerNodeBuilders.registerBuilders(aLibrary, model);
+          MirGlobal.config().getHome(), MirGlobal.config().getFile("Producer.StorageRoot"));
+      SupplementalProducerNodeBuilders.registerBuilders(aLibrary, MirGlobal.config().getHome());
     }
     catch (Throwable t) {
       throw new MirLocalizerFailure(t.getMessage(), t);
     }
   }
 
-  protected void setupFactories(List aFactories, FileMonitor aFileMonitor) throws MirLocalizerExc, MirLocalizerFailure {
-    ProducerConfigReader reader;
-    ProducerNodeBuilderLibrary library = new ProducerNodeBuilderLibrary();
-    setupProducerNodeBuilderLibrary(library);
-
-    aFileMonitor.clear();
-    reader = new ProducerConfigReader();
-
-    File inputFile = new File(MirGlobal.config().getString("Home"), MirGlobal.config().getString("Mir.Localizer.ProducerConfigFile"));
-    aFileMonitor.addFile(inputFile);
-    reader.parse(inputFile, library, aFactories);
-  }
 }
diff --git a/source/mircoders/localizer/basic/MirBasicUtilityFunctions.java b/source/mircoders/localizer/basic/MirBasicUtilityFunctions.java
new file mode 100755 (executable)
index 0000000..363b997
--- /dev/null
@@ -0,0 +1,159 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mircoders.localizer.basic;\r
+\r
+import mir.util.*;\r
+import mir.config.MirPropertiesConfiguration;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+public class MirBasicUtilityFunctions {\r
+  public String encodeXML(Object anObject) throws Exception {\r
+    return HTMLRoutines.encodeXML(StringRoutines.interpretAsString(anObject));\r
+  }\r
+\r
+  public String encodeHTML(Object aString) throws Exception {\r
+    return HTMLRoutines.encodeHTML(StringRoutines.interpretAsString(aString));\r
+  }\r
+\r
+  public String prettyEncodeHTML(Object aString) throws Exception {\r
+    return HTMLRoutines.prettyEncodeHTML(StringRoutines.interpretAsString(aString));\r
+  }\r
+\r
+  public String encodeURI(Object aString) throws Exception {\r
+    return HTMLRoutines.encodeURL(StringRoutines.interpretAsString(aString));\r
+  }\r
+\r
+  public String encodeURI(Object aString, Object anEncoding) throws Exception {\r
+    return HTMLRoutines.encodeURL(\r
+        StringRoutines.interpretAsString(aString),\r
+        StringRoutines.interpretAsString(anEncoding));\r
+  }\r
+\r
+  public String subString(Object aString, Object aFrom) throws Exception {\r
+    return StringRoutines.interpretAsString(aString).substring(StringRoutines.interpretAsInteger(aFrom));\r
+  }\r
+\r
+  public String subString(Object aString, Object aFrom, Object aLength) throws Exception {\r
+    int length = StringRoutines.interpretAsInteger(aLength);\r
+    String target = StringRoutines.interpretAsString(aString);\r
+    if (length<0 || length>target.length()) {\r
+      length=target.length();\r
+    }\r
+\r
+    return target.substring(StringRoutines.interpretAsInteger(aFrom), length);\r
+  }\r
+\r
+  public String escapeJDBCString(Object aString) throws Exception {\r
+    return JDBCStringRoutines.escapeStringLiteral(StringRoutines.interpretAsString(aString));\r
+  }\r
+\r
+  public String constructString(Object aString) throws Exception {\r
+    if (aString==null)\r
+      return StructuredContentParser.constructStringLiteral("");\r
+    else\r
+      return StructuredContentParser.constructStringLiteral(StringRoutines.interpretAsString(aString));\r
+  }\r
+\r
+  public Object parseStructuredString(Object aString) throws Exception {\r
+    if (aString==null)\r
+      return null;\r
+    else\r
+      return StructuredContentParser.parse(StringRoutines.interpretAsString(aString));\r
+  }\r
+\r
+  public boolean isOdd(Object anInteger) throws Exception {\r
+    return (StringRoutines.interpretAsInteger(anInteger) & 1) == 1;\r
+  }\r
+\r
+  public int increment(Object anInteger) throws Exception {\r
+    final Integer ONE = new Integer(1);\r
+\r
+    return increment(anInteger, ONE);\r
+  }\r
+\r
+  public int increment(Object anInteger, Object anIncrement) throws Exception {\r
+    return StringRoutines.interpretAsInteger(anInteger) +\r
+           StringRoutines.interpretAsInteger(anIncrement);\r
+  }\r
+\r
+  public Object subList(Object aList, Object aSkip) throws Exception {\r
+    return subList(aList, aSkip, new Integer(-1));\r
+  }\r
+\r
+  public Object subList(Object aList, Object aSkip, Object aMaxSize) throws Exception {\r
+    int skip = StringRoutines.interpretAsInteger(aSkip);\r
+    int maxSize = StringRoutines.interpretAsInteger(aMaxSize);\r
+\r
+    if (aList instanceof RewindableIterator)\r
+      return new SubsetIterator((RewindableIterator) aList, skip, maxSize);\r
+    else {\r
+      List list = (List) aList;\r
+\r
+      if (skip>=list.size())\r
+        return Collections.EMPTY_LIST;\r
+      if (maxSize<0 || (skip+maxSize)>=list.size())\r
+        return list.subList(skip, list.size());\r
+      else\r
+        return list.subList(skip, skip+maxSize);\r
+    }\r
+  }\r
+\r
+  public int listSize(RewindableIterator anIterator) {\r
+    anIterator.rewind();\r
+    int result=0;\r
+\r
+    while (anIterator.hasNext()) {\r
+      result++;\r
+      anIterator.next();\r
+    }\r
+\r
+    anIterator.rewind();\r
+\r
+    return result;\r
+  }\r
+\r
+  public int listSize(List aList) {\r
+    return aList.size();\r
+  }\r
+\r
+  public Object evaluate(Object aTarget, String anExpression) throws Exception {\r
+    return ParameterExpander.expandExpression(aTarget, anExpression);\r
+  }\r
+\r
+  public String regexpreplace(String aString, String anExpression, String aReplacement) {\r
+    return StringRoutines.performRegularExpressionReplacement(aString, anExpression, aReplacement);\r
+  }\r
+\r
+  public boolean regexpmatch(String aString, String anExpression) {\r
+    return StringRoutines.performRegularExpressionSearch(aString, anExpression);\r
+  }\r
+}\r
diff --git a/source/mircoders/localizer/basic/actions/ArticleTopicAction.java b/source/mircoders/localizer/basic/actions/ArticleTopicAction.java
new file mode 100755 (executable)
index 0000000..7770ff3
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mircoders.localizer.basic.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
+
+import mir.entity.adapter.EntityAdapter;
+import mircoders.localizer.MirLocalizerExc;
+import mircoders.localizer.MirLocalizerFailure;
+import mircoders.localizer.basic.MirBasicAdminInterfaceLocalizer;
+import mircoders.storage.DatabaseContentToTopics;
+
+public class ArticleTopicAction implements MirBasicAdminInterfaceLocalizer.MirSimpleEntityOperation{
+  private String name;
+  private List deleteTopics;
+  private List addTopics;
+
+  public ArticleTopicAction(String aName, int[] aDeleteTopics, int[] anAddTopics) {
+    name = aName;
+    deleteTopics = new ArrayList();
+    for (int i=0; i< aDeleteTopics.length; i++) {
+      deleteTopics.add(Integer.toString(aDeleteTopics[i]));
+    }
+    addTopics = new ArrayList();
+    for (int i=0; i< anAddTopics.length; i++) {
+      addTopics.add(Integer.toString(anAddTopics[i]));
+    }
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public boolean isAvailable(EntityAdapter anEntity) throws MirLocalizerExc, MirLocalizerFailure {
+    return true;
+  }
+
+  public void perform(EntityAdapter aUser, EntityAdapter anEntity) throws MirLocalizerExc, MirLocalizerFailure {
+    DatabaseContentToTopics db = DatabaseContentToTopics.getInstance();
+
+    List topicsToSet = new ArrayList(db.getTopicsOfContent(anEntity.getEntity().getId()));
+
+    topicsToSet.removeAll(deleteTopics);
+    topicsToSet.addAll(addTopics);
+
+    db.setTopics(anEntity.getEntity().getId(), topicsToSet);
+  }
+  public void perform2(EntityAdapter aUser, EntityAdapter anEntity) throws MirLocalizerExc, MirLocalizerFailure {
+    DatabaseContentToTopics db = DatabaseContentToTopics.getInstance();
+
+    List integerTopicsToSet = new ArrayList(db.getTopicsOfContent(anEntity.getEntity().getId()));
+    List topicsToSet = new ArrayList();
+    Iterator i = integerTopicsToSet.iterator();
+    while (i.hasNext()) {
+      topicsToSet.add(i.next().toString());
+    }
+
+    topicsToSet.removeAll(deleteTopics);
+    topicsToSet.addAll(addTopics);
+
+    db.setTopics(anEntity.getEntity().getId(), topicsToSet);
+  }
+}
diff --git a/source/mircoders/localizer/basic/filters/ThrottleFilter.java b/source/mircoders/localizer/basic/filters/ThrottleFilter.java
new file mode 100755 (executable)
index 0000000..65b4732
--- /dev/null
@@ -0,0 +1,237 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mircoders.localizer.basic.filters;\r
+\r
+import mircoders.localizer.basic.MirBasicAntiAbuseFilterTypes;\r
+import mircoders.entity.EntityComment;\r
+\r
+import java.util.*;\r
+\r
+import mir.util.StringRoutines;\r
+import mir.entity.Entity;\r
+import mir.session.Request;\r
+\r
+/**\r
+ * A ip-based throttling filter.\r
+ *\r
+ * <p>\r
+ * Expressions have the form <time in minutes>:<posting limit>\r
+ */\r
+public class ThrottleFilter extends MirBasicAntiAbuseFilterTypes.BasicFilterType {\r
+  private long overallHorizon;\r
+\r
+  private ThrottleManager throttleManager;\r
+\r
+  public ThrottleFilter(String aName, long anOverallHorizon) {\r
+    super(aName);\r
+\r
+    overallHorizon = anOverallHorizon;\r
+    throttleManager = new ThrottleManager(overallHorizon);\r
+  }\r
+\r
+  /** * {@inheritDoc} */\r
+  public boolean validate(String anExpression) {\r
+    List parts = StringRoutines.splitString(anExpression.trim(), ":");\r
+\r
+    try {\r
+      if (parts.size()==2) {\r
+        Integer.parseInt((String) parts.get(0));\r
+        Integer.parseInt((String) parts.get(1));\r
+\r
+        return true;\r
+      }\r
+    }\r
+    catch (Throwable t) {\r
+    }\r
+\r
+    return false;\r
+  }\r
+\r
+  /**\r
+   *\r
+   */\r
+  public boolean test(String anExpression, Entity anEntity, Request aRequest) {\r
+    String ip = aRequest.getHeader("ip");\r
+    int limit;\r
+    long period;\r
+\r
+    List parts = StringRoutines.splitString(anExpression, ":");\r
+\r
+    try {\r
+      period = Integer.parseInt((String) parts.get(0))*1000*60;\r
+      limit = Integer.parseInt((String) parts.get(1));\r
+    }\r
+    catch (Throwable t) {\r
+      return false;\r
+    }\r
+\r
+    return throttleManager.addMessage(ip, anEntity, limit, period);\r
+  };\r
+\r
+  private class ThrottleManager {\r
+    private Map throttles;\r
+    private long overallHorizon;\r
+    private Thread cleanUpThread;\r
+\r
+    public ThrottleManager(long anOverallHorizon) {\r
+      throttles = new HashMap();\r
+      overallHorizon = anOverallHorizon;\r
+\r
+      cleanUpThread = new Thread() {\r
+        public void run() {\r
+          while (true) {\r
+            synchronized(throttles) {\r
+              List toDelete = new ArrayList();\r
+              Iterator i = throttles.entrySet().iterator();\r
+\r
+              while (i.hasNext()) {\r
+                Map.Entry entry = (Map.Entry) i.next();\r
+                try {\r
+                  if (((Throttle) entry.getValue()).flush()) {\r
+                    toDelete.add(entry.getKey());\r
+                  }\r
+                }\r
+                catch (Throwable t) {\r
+                  toDelete.add(entry.getKey());\r
+                }\r
+              }\r
+\r
+              i = toDelete.iterator();\r
+              while (i.hasNext()) {\r
+                throttles.remove(i.next());\r
+              }\r
+            }\r
+            try {\r
+              Thread.sleep(60*10*1000);\r
+            }\r
+            catch (InterruptedException e) {\r
+              break;\r
+            }\r
+          }\r
+        }\r
+      };\r
+\r
+      cleanUpThread.setDaemon(true);\r
+      cleanUpThread.start();\r
+    }\r
+\r
+    public boolean addMessage(String anIP, Entity anEntity, int aLimit, long aPeriod) {\r
+      synchronized (throttles) {\r
+        Throttle throttle = (Throttle) throttles.get(anIP);\r
+\r
+        if (throttle==null) {\r
+          throttle = new Throttle(overallHorizon);\r
+          throttles.put(anIP, throttle);\r
+        }\r
+        return throttle.addMessage(anEntity, aLimit, aPeriod);\r
+      }\r
+    }\r
+\r
+    private class Throttle {\r
+      private List messages;\r
+      private long horizon;\r
+\r
+      public Throttle(long aHorizon) {\r
+        messages = new ArrayList();\r
+        horizon = aHorizon;\r
+      }\r
+\r
+      public boolean flush() {\r
+        long limit = System.currentTimeMillis() - horizon;\r
+\r
+        while (messages.size()>0 && ((Message) messages.get(0)).getTime()<=limit) {\r
+          messages.remove(0);\r
+        }\r
+\r
+        return messages.size()==0;\r
+      }\r
+\r
+      public boolean addMessage(Entity anEntity, int aLimit, long aPeriod) {\r
+        Message lastMessage=null;\r
+        if (messages.size()>0) {\r
+          lastMessage = (Message) messages.get(messages.size()-1);\r
+        }\r
+\r
+        Message newMessage = new Message(anEntity.getId(),\r
+                anEntity instanceof EntityComment, System.currentTimeMillis());\r
+\r
+        if (!newMessage.equals(lastMessage))\r
+          messages.add(newMessage);\r
+\r
+        if (messages.size()>=aLimit) {\r
+          Message message = (Message) messages.get(messages.size()-aLimit);\r
+          return (System.currentTimeMillis()-message.getTime())<aPeriod;\r
+        }\r
+\r
+        return false;\r
+      }\r
+\r
+      private class Message {\r
+        private String id;\r
+        private boolean isComment;\r
+        private long time;\r
+\r
+        public Message(String anId, boolean anIsComment, long aTime) {\r
+          id = anId;\r
+          isComment = anIsComment;\r
+          time = aTime;\r
+        }\r
+\r
+        public String getId() {\r
+          return id;\r
+        }\r
+\r
+        public boolean getIsComment() {\r
+          return isComment;\r
+        }\r
+\r
+        public long getTime() {\r
+          return time;\r
+        }\r
+\r
+        public int hashCode() {\r
+          return getId().hashCode();\r
+        }\r
+\r
+        public boolean equals(Object anObject) {\r
+          if (anObject instanceof Message) {\r
+            Message that = (Message) anObject;\r
+\r
+            if (that.getId().equals(getId()) && that.getIsComment() == getIsComment()) {\r
+              return true;\r
+            }\r
+          }\r
+\r
+          return false;\r
+        }\r
+      }\r
+    }\r
+  }\r
+}\r
diff --git a/source/mircoders/media/AbstractMediaHandler.java b/source/mircoders/media/AbstractMediaHandler.java
new file mode 100755 (executable)
index 0000000..05db1ed
--- /dev/null
@@ -0,0 +1,60 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mircoders.media;\r
+\r
+import mir.media.MediaHandler;\r
+import mir.media.MediaExc;\r
+import mir.media.MediaFailure;\r
+import mir.entity.Entity;\r
+import mir.misc.StringUtil;\r
+\r
+import java.io.File;\r
+\r
+public abstract class AbstractMediaHandler implements MediaHandler {\r
+  public File getStorageFile(Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {\r
+    return new File(new File(getStoragePath()), getRelativeStorageFile(aMedia, aMediaType));\r
+  }\r
+\r
+  public String getRelativeStorageFile(Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {\r
+    String publishPath = aMedia.getFieldValue("publish_path");\r
+\r
+    if (publishPath==null || publishPath.length()==0) {\r
+      String extension = aMediaType.getFieldValue("name");\r
+      String mediaFileName = aMedia.getId() + "." + extension;\r
+      String date = aMedia.getFieldValue("date");\r
+      String datePath = StringUtil.webdbDate2path(date);\r
+      return (new File(datePath, mediaFileName)).getPath();\r
+    }\r
+    else {\r
+      return publishPath;\r
+    }\r
+  }\r
+\r
+}\r
index a4fb96b..2c7877e 100755 (executable)
@@ -34,6 +34,7 @@ import java.awt.RenderingHints;
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
 import java.awt.image.PixelInterleavedSampleModel;
+import java.awt.image.RenderedImage;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -45,7 +46,6 @@ import javax.media.jai.ImageLayout;
 import javax.media.jai.InterpolationBilinear;
 import javax.media.jai.JAI;
 import javax.media.jai.ParameterBlockJAI;
-import javax.media.jai.PlanarImage;
 
 import mir.log.LoggerWrapper;
 
@@ -65,16 +65,16 @@ import com.sun.media.jai.codec.SeekableStream;
 public class ImageProcessor {
   static final LoggerWrapper logger = new LoggerWrapper("media");
 
-  private PlanarImage image;
-  private PlanarImage scaledImage;
+  private RenderedImage image;
+  private RenderedImage scaledImage;
 
-  private byte[] iconData;
-  private byte[] imageData;
-  private int iconWidth;
-  private int iconHeight;
+  public ImageProcessor(RenderedImage anImage) throws IOException {
+    image = anImage;
+    scaledImage = anImage;
+  }
 
   public ImageProcessor(SeekableStream anImageStream) throws IOException {
-    PlanarImage tempImage = JAI.create("stream", anImageStream);
+    RenderedImage tempImage = JAI.create("stream", anImageStream);
     ParameterBlockJAI params = new ParameterBlockJAI("format");
     int bands[];
     int nrComponents;
index 14a0440..ba98564 100755 (executable)
@@ -36,10 +36,9 @@ import mir.media.MediaHandler;
  * Handles audio media, like mp3 and maybe it could also handle some other.
  * It is MediaHandlerGeneric with different icons.
  *
- * @see mir.media.MediaHandlerGeneric
  * @see mir.media.MediaHandler
  * @author mh <mh@nadir.org>
- * @version $Id: MediaHandlerAudio.java,v 1.9.2.2 2003/12/14 16:37:07 zapata Exp $
+ * @version $Id: MediaHandlerAudio.java,v 1.9.2.3 2004/11/21 22:07:14 zapata Exp $
  */
 
 public class MediaHandlerAudio extends MediaHandlerGeneric implements MediaHandler
@@ -52,7 +51,7 @@ public class MediaHandlerAudio extends MediaHandlerGeneric implements MediaHandl
     bigIcon = configuration.getString("Producer.Icon.BigAudio");
   }
 
-  public String getTinyIcon()
+  public String getTinyIconName()
   {
     return tinyIcon;
   }
@@ -62,7 +61,7 @@ public class MediaHandlerAudio extends MediaHandlerGeneric implements MediaHandl
     return bigIcon;
   }
 
-  public String getIconAlt()
+  public String getIconAltName()
   {
     return "Audio";
   }
index 69fa6b7..d023b3d 100755 (executable)
  */
 package  mircoders.media;
 
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Vector;
-
-import javax.servlet.ServletContext;
-
 import mir.config.MirPropertiesConfiguration;
 import mir.entity.Entity;
 import mir.log.LoggerWrapper;
 import mir.media.MediaExc;
 import mir.media.MediaFailure;
-import mir.media.MediaHandler;
-import mir.misc.FileUtil;
 import mir.misc.StringUtil;
+import mir.session.UploadedFile;
+import mir.util.FileFunctions;
+
+import javax.servlet.ServletContext;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
 
 
 /**
@@ -63,133 +60,121 @@ import mir.misc.StringUtil;
  * <p>
  * Of course it implements the MirMediaHandler interface.
  *
- * @see mir.media.MirMediaHandler
+ * @see mir.media.MediaHandler
  * @author mh <mh@nadir.org>
- * @version $Id: MediaHandlerGeneric.java,v 1.20.2.6 2004/01/18 17:30:58 zapata Exp $
+ * @version $Id: MediaHandlerGeneric.java,v 1.20.2.7 2004/11/21 22:07:14 zapata Exp $
  */
 
-public class MediaHandlerGeneric implements MediaHandler
+public class MediaHandlerGeneric extends AbstractMediaHandler
 {
-    protected static MirPropertiesConfiguration configuration;
-    protected static String imageHost;
-    protected static String imageRoot;
-
-    protected LoggerWrapper logger;
-
-    static {
-      try {
-        configuration = MirPropertiesConfiguration.instance();
-      }
-      catch (MirPropertiesConfiguration.PropertiesConfigExc e) {
-      }
-      imageHost = configuration.getString("Producer.Image.Host");
-      imageRoot = configuration.getString("Producer.ImageRoot");
-    }
+  protected static MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
 
-    public MediaHandlerGeneric() {
-      logger = new LoggerWrapper("Media.Generic");
-    }
+  protected LoggerWrapper logger = new LoggerWrapper("Media.Generic");
 
-    public void store (InputStream in, Entity ent, Entity mediaTypeEnt ) throws MediaExc, MediaFailure {
-      String ext = mediaTypeEnt.getFieldValue("name");
-      String mediaFname = ent.getId() + "." + ext;
-      String date = ent.getFieldValue("date");
-      String datePath = StringUtil.webdbDate2path(date);
-      try {
-        long size = FileUtil.write(getStoragePath() + File.separator + datePath +
-                                   File.separator + mediaFname, in);
-        ent.setFieldValue("publish_path", datePath + mediaFname);
-        ent.setFieldValue("size", new Long(size).toString());
-        ent.update();
-      }
-      catch (Throwable e) {
-        logger.error("MediaHandlerGeneric.set: " + e.toString());
-        throw new MediaFailure(e);
-      }
+  /** {@inheritDoc} */
+  public void store(File aFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    try {
+      FileFunctions.move(aFile, getStorageFile(aMedia, aMediaType));
+
+      aMedia.setFieldValue("publish_path", getRelativeStorageFile(aMedia, aMediaType));
+      aMedia.setFieldValue("size", Long.toString(getStorageFile(aMedia, aMediaType).length()));
+      aMedia.update();
+    }
+    catch (Throwable e) {
+      logger.error("MediaHandlerGeneric.set: " + e.toString());
+      throw new MediaFailure(e);
     }
+  }
 
-    public void produce (Entity ent, Entity mediaTypeEnt ) throws MediaExc, MediaFailure {
-      //check first if the media file exist since produced
-      //location is also the storage location
+  /** {@inheritDoc} */
+  public void store(UploadedFile anUploadedFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    try {
+      anUploadedFile.writeToFile(getStorageFile(aMedia, aMediaType));
 
-      String date = ent.getFieldValue("date");
-      String datePath = StringUtil.webdbDate2path(date);
-      String relPath = datePath+ent.getId()+"."+mediaTypeEnt.getFieldValue("name");
-      String fname = getStoragePath()+relPath;
-      if(! new File(fname).exists())
-        throw new MediaExc("error in MirMediaHandler.produce(): " + relPath + " does not exist!");
+      aMedia.setFieldValue("publish_path", getRelativeStorageFile(aMedia, aMediaType));
+      aMedia.setFieldValue("size", Long.toString(getStorageFile(aMedia, aMediaType).length()));
+      aMedia.update();
     }
-
-    public InputStream getMedia (Entity ent, Entity mediaTypeEnt) throws MediaExc, MediaFailure {
-      String publishPath = ent.getFieldValue("publish_path");
-      String fname = getStoragePath()+publishPath;
-      File f = new File(fname);
-      if(! f.exists())
-        throw new MediaExc("error in MirMediaHandler.getMedia(): " + fname + " does not exist!");
-
-      BufferedInputStream inputStream;
-      try {
-        inputStream = new BufferedInputStream(new FileInputStream(f));
-      }
-      catch (Throwable e) {
-        throw new MediaFailure("MediaHandlerGeneric.getMedia(): " + e.toString(), e);
-      }
-
-      return inputStream;
+    catch (Throwable e) {
+      logger.error("MediaHandlerGeneric.set: " + e.toString());
+      throw new MediaFailure(e);
     }
+  }
+
+  /** {@inheritDoc} */
+  public void store(InputStream anInputStream, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    try {
+      FileFunctions.copy(anInputStream, getStorageFile(aMedia, aMediaType));
 
-    public InputStream getThumbnail (Entity ent) throws MediaExc, MediaFailure {
-      return null;
+      aMedia.setFieldValue("publish_path", getRelativeStorageFile(aMedia, aMediaType));
+      aMedia.setFieldValue("size", Long.toString(getStorageFile(aMedia, aMediaType).length()));
+      aMedia.update();
     }
+    catch (Throwable e) {
+      logger.error("MediaHandlerGeneric.set: " + e.toString());
+      throw new MediaFailure(e);
+    }
+  }
+
+  public void produce(Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    if (!getStorageFile(aMedia, aMediaType).exists())
+      throw new MediaExc("error in producing media:: " + getStorageFile(aMedia, aMediaType) + " does not exist!");
+  }
+
+  /**
+   * Get access to the raw media data by an {@link InputStream}
+   */
+  public InputStream getMedia(Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    File file = getStorageFile(aMedia, aMediaType);
+    if (!file.exists())
+      throw new MediaExc("error in MirMediaHandler.getMedia(): " + file + " does not exist!");
+
+    try {
+      return new BufferedInputStream(new FileInputStream(file));
+    }
+    catch (Throwable e) {
+      throw new MediaFailure("MediaHandlerGeneric.getMedia(): " + e.toString(), e);
+    }
+  }
 
-    public String getThumbnailMimeType (Entity aMediaEntity, Entity aMediaType) throws MediaExc, MediaFailure {
-      ServletContext servletContext = MirPropertiesConfiguration.getContext();
-      String fileName = aMediaEntity.getId()+"."+aMediaType.getFieldValue("name");
+  public InputStream getThumbnail(Entity ent) throws MediaExc, MediaFailure {
+    return null;
+  }
 
-      return servletContext.getMimeType(fileName);
-    };
+  public String getThumbnailMimeType(Entity aMediaEntity, Entity aMediaType) throws MediaExc, MediaFailure {
+    ServletContext servletContext = MirPropertiesConfiguration.getContext();
+    String fileName = aMediaEntity.getId() + "." + aMediaType.getFieldValue("name");
 
-    public String getStoragePath()
-    {
-        return configuration.getString("Producer.Media.Path");
-    }
+    return servletContext.getMimeType(fileName);
+  };
 
-    public String getIconStoragePath()
-    {
-        return configuration.getString("Producer.Image.IconPath");
-    }
+  public String getStoragePath() {
+    return configuration.getString("Producer.Media.Path");
+  }
 
-    public String getPublishHost()
-    {
-        return StringUtil.removeSlash(configuration.getString("Producer.Media.Host"));
-    }
+  public String getIconStoragePath() {
+    return configuration.getString("Producer.Image.IconPath");
+  }
 
-    public String getTinyIconName()
-    {
-        return configuration.getString("Producer.Icon.TinyText");
-    }
+  public String getPublishHost() {
+    return StringUtil.removeSlash(configuration.getString("Producer.Media.Host"));
+  }
 
-    public String getBigIconName()
-    {
-        return configuration.getString("Producer.Icon.BigText");
-    }
+  public String getTinyIconName() {
+    return configuration.getString("Producer.Icon.TinyText");
+  }
 
-    public String getIconAltName()
-    {
-        return "Generic media";
-    }
+  public String getBigIconName() {
+    return configuration.getString("Producer.Icon.BigText");
+  }
 
-    public List getURL(Entity ent, Entity mediaTypeEnt)
-    {
-      List theList = new Vector();
-      theList.add(ent);
-      return theList;
-    }
+  public String getIconAltName() {
+    return "Generic media";
+  }
 
-    public String getDescr( Entity mediaType)
-    {
-      return mediaType.getFieldValue("mime_type");
-    }
+  public String getDescr(Entity mediaType) {
+    return mediaType.getFieldValue("mime_type");
+  }
 
 }
 
index 1e4f9fa..9479315 100755 (executable)
@@ -31,11 +31,13 @@ package mircoders.media;
 
 import java.io.File;
 import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.util.List;
 import java.util.Vector;
+import java.util.ArrayList;
 
 import mir.config.MirPropertiesConfiguration;
-import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
 import mir.entity.Entity;
 import mir.log.LoggerWrapper;
 import mir.media.MediaExc;
@@ -43,6 +45,8 @@ import mir.media.MediaFailure;
 import mir.media.MediaHandler;
 import mir.misc.FileUtil;
 import mir.misc.StringUtil;
+import mir.session.UploadedFile;
+import mir.session.SessionExc;
 import mircoders.entity.EntityImages;
 
 /**
@@ -57,29 +61,19 @@ import mircoders.entity.EntityImages;
  * representation stuff (WebdbImage) happen here.
  * -mh 01.03.2002
  *
- * @see mir.media.MirMediaHandler
+ * @see mir.media.MediaHandler
  * @author mh
- * @version $Id: MediaHandlerImages.java,v 1.23.2.4 2004/01/18 17:30:58 zapata Exp $
+ * @version $Id: MediaHandlerImages.java,v 1.23.2.5 2004/11/21 22:07:14 zapata Exp $
  */
 
 
-public abstract class MediaHandlerImages implements MediaHandler
-{
-  protected static MirPropertiesConfiguration configuration;
+public abstract class MediaHandlerImages extends AbstractMediaHandler implements MediaHandler {
+  protected static MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
   protected static final String PNG = "PNG";
   protected static final String JPEG = "JPEG";
 
   protected LoggerWrapper logger;
 
-  static {
-    try {
-      configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (PropertiesConfigExc e) {
-      throw new RuntimeException("Can't get configuration: " + e.getMessage());
-    }
-  }
-
   abstract String getType();
 
   public MediaHandlerImages() {
@@ -101,15 +95,32 @@ public abstract class MediaHandlerImages implements MediaHandler
     return inputStream;
   }
 
-  public void store(InputStream in, Entity ent, Entity mediaTypeEnt) throws MediaExc, MediaFailure {
+  public void store(UploadedFile anUploadedFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    try {
+      store(anUploadedFile.getInputStream(), aMedia, aMediaType);
+    }
+    catch (SessionExc e) {
+      throw new MediaFailure(e);
+    }
+  }
 
+  public void store(InputStream in, Entity ent, Entity mediaTypeEnt) throws MediaExc, MediaFailure {
     try {
-      ((EntityImages)ent).setImage(in, getType());
+      ((EntityImages) ent).setImage(in, getType());
     }
     catch (Throwable e) {
-      logger.error("MediaHandlerImages.set: "+e.getMessage());
-      e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
+      logger.error("MediaHandlerImages.store: "+e.toString());
+      e.printStackTrace(logger.asPrintWriter(LoggerWrapper.ERROR_MESSAGE));
 
+      throw new MediaExc("A problem has occurred processing the media file: " + e.toString());
+    }
+  }
+
+  public void store(File aFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    try {
+      store(new FileInputStream(aFile), aMedia, aMediaType);
+    }
+    catch (FileNotFoundException e) {
       throw new MediaFailure(e);
     }
   }
@@ -128,7 +139,7 @@ public abstract class MediaHandlerImages implements MediaHandler
         ent.getFieldValue("image_data")!= null) {
       // make icon
       try {
-        InputStream in = ((EntityImages)ent).getIcon();
+        InputStream in = ((EntityImages) ent).getIcon();
         FileUtil.write(iconFilePath, in);
         in = ((EntityImages)ent).getImage();
         FileUtil.write(productionFilePath, in);
@@ -148,11 +159,10 @@ public abstract class MediaHandlerImages implements MediaHandler
     }
   }
 
-
   public InputStream getThumbnail(Entity ent) throws MediaExc, MediaFailure {
     InputStream in;
     try {
-      in = ((EntityImages)ent).getIcon();
+      in = ((EntityImages) ent).getIcon();
     }
     catch (Throwable e) {
       logger.error("MediaHandlerImages.getIcon: " + e.toString());
@@ -162,13 +172,7 @@ public abstract class MediaHandlerImages implements MediaHandler
     return in;
   }
 
-  public List getURL(Entity ent, Entity mediaTypeEnt) {
-    List theList = new Vector();
-    theList.add(ent);
-    return theList;
-  }
-
-  public String getStoragePath() {
+ public String getStoragePath() {
     return configuration.getString("Producer.Image.Path");
   }
 
@@ -191,6 +195,7 @@ public abstract class MediaHandlerImages implements MediaHandler
   public String getIconAltName() {
     return "Image";
   }
+
   public String getDescr(Entity mediaType) {
     return "image/jpeg";
   }
index 7d90b7f..c3a2a89 100755 (executable)
@@ -35,7 +35,6 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
-import mir.config.MirPropertiesConfiguration;
 import mir.entity.Entity;
 import mir.log.LoggerWrapper;
 import mir.media.MediaExc;
@@ -59,14 +58,6 @@ public class MediaHandlerImagesExtern extends MediaHandlerGeneric
   public MediaHandlerImagesExtern() {
 
     logger = new LoggerWrapper("Media.Images.Extern");
-    try {
-      MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (Throwable t) {
-      logger.fatal("MediaHandlerImagesExtern: can't get configuration");
-
-      throw new RuntimeException(t.toString());
-    }
 
     maxIconSize = configuration.getInt("Producer.Image.MaxIconSize");
     minDescaleRatio = configuration.getFloat("Producer.Image.MinDescalePercentage")/100;
@@ -115,22 +106,25 @@ public class MediaHandlerImagesExtern extends MediaHandlerGeneric
       }
     }
     catch(Throwable t) {
-      logger.error("MediaHandlerImagesExtern.produce: " + t.getMessage());
+      logger.error("MediaHandlerImagesExtern.produce: " + t.toString());
       t.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
       throw new MediaFailure(t.getMessage(), t);
     }
   }
 
 
-  public InputStream getIcon(Entity anImageEntity) throws MediaExc, MediaFailure {
+  /** {@inheritDoc} */
+  public InputStream getThumbnail(Entity anImageEntity) throws MediaExc, MediaFailure {
     try {
-      String filePath =
-          configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path");
+      File file = new File(configuration.getString("Producer.StorageRoot") + anImageEntity.getFieldValue("icon_path"));
 
-      logger.info(filePath);
+      if (!file.exists()) {
+        // hackish
+        file = new File(configuration.getHome(), "../img/photo_big.gif");
+      }
 
       return new BufferedInputStream(
-        new FileInputStream(new File(filePath)),8192);
+        new FileInputStream(file),8192);
     }
     catch (Throwable t) {
       return null;
index b6c2303..ec32399 100755 (executable)
@@ -39,10 +39,10 @@ import mir.media.MediaHandler;
  * It implements the MirMediaHandler interface.
  * <p>
  *
- * @see mir.media.MirMediaHandler
+ * @see mir.media.MediaHandler
  * @see mircoders.media.MediaHandlerImages
  * @author mh, mir-coders group
- * @version $Id: MediaHandlerImagesJpeg.java,v 1.6.2.1 2003/12/14 16:37:08 zapata Exp $
+ * @version $Id: MediaHandlerImagesJpeg.java,v 1.6.2.2 2004/11/21 22:07:14 zapata Exp $
  */
 
 
index ed96887..2deb304 100755 (executable)
  */
 package  mircoders.media;
 
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
 import mir.entity.Entity;
 import mir.log.LoggerWrapper;
 import mir.media.MediaExc;
@@ -43,6 +37,8 @@ import mir.media.MediaHandler;
 import mir.misc.FileUtil;
 import mir.misc.StringUtil;
 
+import java.io.StringReader;
+
 /**
  * Please note: this media handler produces
  * 3 media files, the raw .mp3, a .m3u which is
@@ -67,7 +63,7 @@ import mir.misc.StringUtil;
  *
  * @see mir.media.MediaHandler
  * @author mh <mh@nadir.org>
- * @version $Id: MediaHandlerMp3.java,v 1.15.2.4 2004/01/18 17:30:59 zapata Exp $
+ * @version $Id: MediaHandlerMp3.java,v 1.15.2.5 2004/11/21 22:07:14 zapata Exp $
  */
 
 public class MediaHandlerMp3 extends MediaHandlerAudio implements MediaHandler
@@ -105,34 +101,6 @@ public class MediaHandlerMp3 extends MediaHandlerAudio implements MediaHandler
     }
   }
 
-  public List getURL(Entity ent, Entity mediaTypeEnt) {
-    List theList = new Vector();
-
-    //String stringSize = ent.getFieldValue("size");
-    //int size = Integer.parseInt(stringSize, 10)/1024;
-    theList.add(ent);
-
-    String basePath = StringUtil.regexpReplace(ent.getFieldValue("publish_path"),
-                                               ".mp3$", "");
-
-    // @todo the texts ("title") below urgently need to be sanely localizaeble
-    // somehow
-    Map m3uHash = new HashMap();
-    m3uHash.put("publish_path", basePath + ".m3u");
-    m3uHash.put("publish_server", ent.getFieldValue("publish_server"));
-    m3uHash.put("title", "stream URL");
-    theList.add(m3uHash);
-
-    Map plsHash = new HashMap();
-    plsHash.put("publish_path", basePath + ".pls");
-    plsHash.put("publish_server", ent.getFieldValue("publish_server"));
-    plsHash.put("title", "playlist URL");
-    theList.add(plsHash);
-
-    return theList;
-
-  }
-
   public String getDescr(Entity mediaType) {
     return "mp3";
   }
index d518f8b..0e0a457 100755 (executable)
@@ -106,35 +106,6 @@ public class MediaHandlerOgg extends MediaHandlerAudio implements MediaHandler
     }
   }
 
-  public List getURL(Entity ent, Entity mediaTypeEnt) {
-    List theList = new Vector();
-
-    //String stringSize = ent.getFieldValue("size");
-    //int size = Integer.parseInt(stringSize, 10)/1024;
-    theList.add(ent);
-
-    String basePath = StringUtil.regexpReplace(ent.getFieldValue("publish_path"),
-                                               ".ogg$", "");
-
-    // @todo the texts ("title") below urgently need to be sanely localizaeble
-    // somehow
-    //no .m3u!
-    //Map m3uHash = new HashMap();
-    //m3uHash.put("publish_path", basePath + ".m3u");
-    //m3uHash.put("publish_server", ent.getFieldValue("publish_server"));
-    //m3uHash.put("title", "stream URL");
-    //theList.add(m3uHash);
-
-    Map plsHash = new HashMap();
-    plsHash.put("publish_path", basePath + ".pls");
-    plsHash.put("publish_server", ent.getFieldValue("publish_server"));
-    plsHash.put("title", "playlist URL");
-    theList.add(plsHash);
-
-    return theList;
-
-  }
-
   public String getDescr(Entity mediaType) {
     return "ogg";
   }
index 7e0ce64..3cbeb21 100755 (executable)
@@ -53,7 +53,7 @@ import mir.misc.StringUtil;
  * @see mir.media.MediaHandlerGeneric
  * @see mir.media.MediaHandler
  * @author john <john@manifestor.org>, mh <heckmann@hbe.ca>
- * @version $Id: MediaHandlerRealAudio.java,v 1.19.2.4 2004/01/18 17:30:59 zapata Exp $
+ * @version $Id: MediaHandlerRealAudio.java,v 1.19.2.5 2004/11/21 22:07:14 zapata Exp $
  */
 
 
@@ -87,28 +87,6 @@ public class MediaHandlerRealAudio extends MediaHandlerAudio implements MediaHan
     }
   }
 
-  public List getURL(Entity ent, Entity mediaTypeEnt)
-  {
-    List theList = new Vector();
-
-    //String stringSize = ent.getFieldValue("size");
-    //int size = Integer.parseInt(stringSize, 10)/1024;
-    theList.add(ent);
-
-    String basePath=StringUtil.regexpReplace(ent.getFieldValue("publish_path"),
-                                            ".ra$","");
-
-    // @todo the texts ("title") below urgently need to be sanely localizaeble
-    // somehow
-    Map ramHash = new HashMap();
-    ramHash.put("publish_path", basePath+".ram");
-    ramHash.put("publish_server", configuration.getString("Producer.Media.Host"));
-    ramHash.put("title", "stream URL");
-    theList.add(ramHash);
-
-    return theList;
-  }
-
   public String getStoragePath()
   {
     return configuration.getString("Producer.RealMedia.Path");
index 849461c..0807c39 100755 (executable)
  */
 package  mircoders.media;
 
-import java.io.File;
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
 import mir.entity.Entity;
 import mir.log.LoggerWrapper;
 import mir.media.MediaExc;
@@ -44,6 +37,9 @@ import mir.media.MediaHandler;
 import mir.misc.FileUtil;
 import mir.misc.StringUtil;
 
+import java.io.File;
+import java.io.StringReader;
+
 
 
 /**
@@ -51,10 +47,9 @@ import mir.misc.StringUtil;
  *
  * 03.2002 - reworked Realmedia handling. -mh
  *
- * @see mir.media.MediaHandlerGeneric
  * @see mir.media.MediaHandler
  * @author john <john@manifestor.org>, mh <mh@nadir.org>
- * @version $Id: MediaHandlerRealVideo.java,v 1.19.2.4 2004/01/18 17:30:59 zapata Exp $
+ * @version $Id: MediaHandlerRealVideo.java,v 1.19.2.5 2004/11/21 22:07:14 zapata Exp $
  */
 
 
@@ -89,28 +84,6 @@ public class MediaHandlerRealVideo extends MediaHandlerVideo implements MediaHan
     }
   }
 
-  public List getURL(Entity ent, Entity mediaTypeEnt) {
-    List theList = new Vector();
-
-    //String stringSize = ent.getFieldValue("size");
-    //int size = Integer.parseInt(stringSize, 10)/1024;
-    theList.add(ent);
-
-    String basePath=StringUtil.regexpReplace(ent.getFieldValue("publish_path"),
-                                            ".rm$","");
-
-    // @todo the texts ("title") below urgently need to be sanely localizaeble
-    // somehow
-    Map ramHash = new HashMap();
-    ramHash.put("publish_path", basePath+".ram");
-    ramHash.put("publish_server", configuration.getString("Producer.Media.Host"));
-    ramHash.put("title", "stream URL");
-    theList.add(ramHash);
-
-    return theList;
-
-  }
-
   public String getStoragePath() {
     return configuration.getString("Producer.RealMedia.Path");
   }
index c5830a1..4ba84d3 100755 (executable)
@@ -40,7 +40,7 @@ import mir.media.MediaHandler;
  * @see mir.media.MediaHandlerGeneric
  * @see mir.media.MediaHandler
  * @author john <john@manifestor.org>
- * @version $Id: MediaHandlerVideo.java,v 1.9.2.1 2003/12/14 16:37:08 zapata Exp $
+ * @version $Id: MediaHandlerVideo.java,v 1.9.2.2 2004/11/21 22:07:14 zapata Exp $
  */
 
 public class MediaHandlerVideo extends MediaHandlerGeneric implements MediaHandler
@@ -53,7 +53,7 @@ public class MediaHandlerVideo extends MediaHandlerGeneric implements MediaHandl
     bigIcon = configuration.getString("Producer.Icon.BigVideo");
   }
 
-  public String getTinyIcon() {
+  public String getTinyIconName() {
     return tinyIcon;
   }
 
@@ -61,7 +61,7 @@ public class MediaHandlerVideo extends MediaHandlerGeneric implements MediaHandl
     return bigIcon;
   }
 
-  public String getIconAlt() {
+  public String getIconAltName() {
     return "Video";
   }
 
index f423ddf..8825e89 100755 (executable)
  */
 package mircoders.media;
 
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Map;
-
 import mir.entity.Entity;
-import mir.media.MediaExc;
+import mir.log.LoggerWrapper;
 import mir.media.MediaFailure;
-import mircoders.media.MediaHelper;
 import mir.media.MediaHandler;
 import mir.misc.StringUtil;
 import mir.session.UploadedFile;
 import mir.storage.Database;
+import mir.util.FileFunctions;
 import mircoders.module.ModuleMediaType;
 
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+
 public class MediaUploadProcessor {
-  public static Entity processMediaUpload(UploadedFile aFile, Map aValues) throws MediaExc, MediaFailure {
-    String mediaId;
+  private static LoggerWrapper logger = new LoggerWrapper("Media.UploadProcessor");
+  private static ModuleMediaType mediaTypeModule = new ModuleMediaType();
+
+  /**
+   * Processes an uploaded media file.
+   * Will create the media entity and so on. 
+   */
+  public static Entity processMediaUpload(UploadedFile aFile, Map aValues) throws UnsupportedMediaTypeExc, MediaFailure {
     MediaHandler mediaHandler;
-    Entity mediaType;
-    ModuleMediaType mediaTypeModule;
+    Entity mediaType = null;
     Database mediaStorage;
     Map values = new HashMap();
-    String MediaId;
     Entity mediaEntity;
 
+    String contentType = aFile.getContentType();
+    logger.debug("processing media upload of " + aFile.getFileName() + " (content type = " + contentType + ")");
 
-    try {
-      String contentType = aFile.getContentType();
-
-      if (contentType.equals("text/plain") ||
-          contentType.equals("application/octet-stream") ||
-          contentType == null) {
-        throw new MediaExc("Invalid content-type: " + contentType);
-      }
-
-      values.putAll(aValues);
-      values.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
-      values.put("is_produced", "0");
-
-      mediaTypeModule = new ModuleMediaType();
+    if (contentType!=null) {
       mediaType = mediaTypeModule.findMediaTypeForMimeType(contentType);
+    }
 
-      try {
-        mediaHandler = MediaHelper.getHandler(mediaType);
-        mediaStorage = MediaHelper.getStorage(mediaType, mediaType.getFieldValue("tablename"));
-      }
-      catch (Throwable e) {
-        throw new MediaFailure(e);
-      }
+    if (mediaType==null) {
+      String extension = FileFunctions.getExtension(aFile.getFileName());
+      mediaType = mediaTypeModule.findMediaTypeForExtension(extension);
+    }
+
+    if (mediaType==null) {
+      throw new UnsupportedMediaTypeExc("Media " + aFile.getFileName() + " " +
+          (aFile!=null?"("+aFile.getContentType()+") ":"") + " not supported", aFile.getContentType());
+    }
 
-      values.put("to_media_type", mediaType.getId());
+    values.putAll(aValues);
+    values.put("date", StringUtil.date2webdbDate(new GregorianCalendar()));
+    values.put("is_produced", "0");
 
-      try {
-        mediaEntity = (Entity) mediaStorage.getEntityClass().newInstance();
-        mediaEntity.setStorage(mediaStorage);
-      }
-      catch (Throwable e) {
-        throw new MediaFailure(e);
-      }
+    try {
+      mediaHandler = MediaHelper.getHandler(mediaType);
+      mediaStorage = MediaHelper.getStorage(mediaType, mediaType.getFieldValue("tablename"));
+    }
+    catch (Throwable e) {
+      throw new MediaFailure(e);
+    }
 
-      mediaEntity.setFieldValues(values);
-      mediaId = mediaEntity.insert();
+    values.put("to_media_type", mediaType.getId());
 
-      try {
-        mediaHandler.store(aFile.getInputStream(), mediaEntity, mediaType);
-      }
-      catch (Throwable e) {
-        throw new MediaFailure(e);
-      }
+    try {
+      mediaEntity = (Entity) mediaStorage.getEntityClass().newInstance();
+      mediaEntity.setStorage(mediaStorage);
+    }
+    catch (Throwable e) {
+      throw new MediaFailure(e);
+    }
 
-      return mediaEntity;
+    mediaEntity.setFieldValues(values);
+    try {
+      mediaEntity.insert();
+      mediaHandler.store(aFile, mediaEntity, mediaType);
     }
     catch (Throwable e) {
       throw new MediaFailure(e);
     }
 
+    return mediaEntity;
   }
 }
\ No newline at end of file
index 6603d1c..8401074 100755 (executable)
@@ -1,15 +1,19 @@
 package mircoders.media;
 
-import mir.media.*;
+import mir.entity.Entity;
+import mir.media.MediaExc;
+import mir.media.MediaFailure;
+import mir.media.MediaHandler;
+import mir.session.UploadedFile;
+
+import java.io.File;
 import java.io.InputStream;
-import mir.entity.*;
-import java.util.List;
-import java.util.ArrayList;
 
 /**
  * <p>URLMediaHandler</p>
  * <p>Description:
- *     This is a media handler for media that are only known by url.
+ *     This is a media handler for externally stored media.
+ *     The media is presented by its url.
  * </p>
  * @author Zapata
  */
@@ -25,11 +29,41 @@ public class URLMediaHandler implements MediaHandler {
     iconAlternative = anIconAlternative;
   }
 
+  /**
+   * {@inheritDoc}
+   *
+   * Since this media handler assumes the media is stored on a wholly different
+   * server, this operation is not applicable
+   */
+  public void store(UploadedFile anUploadedFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * Since this media handler assumes the media is stored on a wholly different
+   * server, this operation is not applicable
+   */
   public void store(InputStream anInputStream, Entity anEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure {
     throw new UnsupportedOperationException();
-  };
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * Since this media handler assumes the media is stored on a wholly different
+   * server, this operation is not applicable
+   */
+  public void store(File aFile, Entity aMedia, Entity aMediaType) throws MediaExc, MediaFailure {
+    throw new UnsupportedOperationException();
+  }
 
+  /**
+   * {@inheritDoc}
+   */
   public void produce(Entity anEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure {
+    // nothing to do here
   }
 
   public InputStream getMedia(Entity anEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure {
@@ -44,17 +78,6 @@ public class URLMediaHandler implements MediaHandler {
     return "application/octetstream";
   }
 
-  public List getURL(Entity aMediaEntity, Entity aMediaTypeEntity) throws MediaExc, MediaFailure {
-    List result = new ArrayList();
-    result.add(aMediaTypeEntity.getFieldValue("publish_server")+aMediaTypeEntity.getFieldValue("publish_path"));
-
-    return result;
-  }
-
-  public Object getURLs(Entity ent, Entity mediaTypeEnt) throws MediaExc, MediaFailure {
-    return null;
-  }
-
   public String getStoragePath () throws MediaExc, MediaFailure {
     throw new UnsupportedOperationException();
   }
@@ -79,7 +102,7 @@ public class URLMediaHandler implements MediaHandler {
     return iconAlternative;
   }
 
-  public String getDescr (Entity mediaTypeEnt) {
+  public String getDescr(Entity mediaTypeEnt) {
     return "Url";
   }
 }
\ No newline at end of file
diff --git a/source/mircoders/media/UnsupportedMediaTypeExc.java b/source/mircoders/media/UnsupportedMediaTypeExc.java
new file mode 100755 (executable)
index 0000000..e032050
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * Copyright (C) 2001, 2002 The Mir-coders group\r
+ *\r
+ * This file is part of Mir.\r
+ *\r
+ * Mir is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Mir is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Mir; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ *\r
+ * In addition, as a special exception, The Mir-coders gives permission to link\r
+ * the code of this program with  any library licensed under the Apache Software License,\r
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library\r
+ * (or with modified versions of the above that use the same license as the above),\r
+ * and distribute linked combinations including the two.  You must obey the\r
+ * GNU General Public License in all respects for all of the code used other than\r
+ * the above mentioned libraries.  If you modify this file, you may extend this\r
+ * exception to your version of the file, but you are not obligated to do so.\r
+ * If you do not wish to do so, delete this exception statement from your version.\r
+ */\r
+package mircoders.media;\r
+\r
+import multex.Exc;\r
+\r
+public class UnsupportedMediaTypeExc extends Exc {\r
+  private String mimeType;\r
+\r
+  public UnsupportedMediaTypeExc(String aMessage, String aMimeType) {\r
+    super(aMessage);\r
+    mimeType = aMimeType;\r
+  }\r
+\r
+  public String getMimeType() {\r
+    return mimeType;\r
+  }\r
+}\r
index 8a12767..953a732 100755 (executable)
@@ -33,18 +33,14 @@ import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
 import mir.module.ModuleExc;
 import mir.module.ModuleFailure;
-import mir.storage.StorageObject;
 import mir.util.JDBCStringRoutines;
+import mircoders.storage.DatabaseArticleType;
 
 public class ModuleArticleType extends AbstractModule {
   static LoggerWrapper logger = new LoggerWrapper("Module.ArticleType");
 
-  public ModuleArticleType (StorageObject theStorage)  {
-
-    if (theStorage == null)
-      logger.warn("ModuleArticleType -- StorageObject was null!");
-
-    this.storage = theStorage;
+  public ModuleArticleType() {
+    super(DatabaseArticleType.getInstance());
   }
 
   public String articleTypeIdForName(String aName) throws ModuleExc, ModuleFailure {
index 16dba4c..7c0e6d2 100755 (executable)
@@ -31,7 +31,7 @@ package mircoders.module;
 
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
-import mir.storage.StorageObject;
+import mircoders.storage.DatabaseBreaking;
 
 
 
@@ -46,11 +46,8 @@ public class ModuleBreaking extends AbstractModule
 {
   static LoggerWrapper logger = new LoggerWrapper("Module.Breaking");
 
-  public ModuleBreaking (StorageObject theStorage)
+  public ModuleBreaking ()
   {
-    if (theStorage == null) logger.warn("ModuleBreaking -- StorageObject was null!");
-    this.storage = theStorage;
+    super (DatabaseBreaking.getInstance());
   }
-
-// Methoden
 }
index 853eb25..a66d4cc 100755 (executable)
  */
 package mircoders.module;
 
-import java.util.Map;
-
 import mir.entity.Entity;
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
 import mir.module.ModuleExc;
 import mir.module.ModuleFailure;
-import mir.storage.StorageObject;
+import mircoders.storage.DatabaseComment;
 import mircoders.storage.DatabaseContent;
 
+import java.util.Map;
+
 
 /*
  *  ModuleComment - methods and access for comments
@@ -50,10 +50,9 @@ public class ModuleComment extends AbstractModule
 {
   static LoggerWrapper logger = new LoggerWrapper("Module.Comment");
 
-  public ModuleComment(StorageObject theStorage)
+  public ModuleComment()
   {
-    if (theStorage == null) logger.warn("StorageObject was null!");
-    this.storage = theStorage;
+    super(DatabaseComment.getInstance());
   }
 
   public void deleteById (String anId) throws ModuleExc, ModuleFailure {
index f0d9a98..8a9417d 100755 (executable)
@@ -33,17 +33,14 @@ import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
 import mir.module.ModuleExc;
 import mir.module.ModuleFailure;
-import mir.storage.StorageObject;
 import mir.util.JDBCStringRoutines;
+import mircoders.storage.DatabaseCommentStatus;
 
 public class ModuleCommentStatus extends AbstractModule {
   static LoggerWrapper logger = new LoggerWrapper("Module.CommentStatus");
 
-  public ModuleCommentStatus (StorageObject theStorage)        {
-    if (theStorage == null)
-      logger.warn("ModuleCommentStatus -- StorageObject was null!");
-
-    this.storage = theStorage;
+  public ModuleCommentStatus ()        {
+    super(DatabaseCommentStatus.getInstance());
   }
 
   public String commentStatusIdForName(String aName) throws ModuleExc, ModuleFailure {
index 7ba9082..d3877d5 100755 (executable)
@@ -32,9 +32,9 @@ package mircoders.module;
 
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
-import mir.storage.StorageObject;
 import mir.util.JDBCStringRoutines;
-import mircoders.global.*;
+import mircoders.global.MirGlobal;
+import mircoders.storage.DatabaseContent;
 
 /**
  *
@@ -51,11 +51,7 @@ public class ModuleContent extends AbstractModule
   static LoggerWrapper logger = new LoggerWrapper("Module.Content");
 
   public ModuleContent() {
-    super();
-  }
-
-  public ModuleContent(StorageObject aStorage) {
-    storage = aStorage;
+    super(DatabaseContent.getInstance());
   }
 
   public void expireArticleLock(String anId, String aUserId) {
index eaef33f..f621448 100755 (executable)
@@ -31,14 +31,12 @@ package mircoders.module;
 
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
-import mir.storage.StorageObject;
+import mircoders.storage.DatabaseImages;
 
 public class ModuleImages extends AbstractModule {
   static LoggerWrapper logger = new LoggerWrapper("Module.Images");
 
-  public ModuleImages(StorageObject theStorage) {
-    if (theStorage == null)
-      logger.warn("ModuleImages: StorageObject was null!");
-    this.storage = theStorage;
+  public ModuleImages() {
+    super(DatabaseImages.getInstance());
   }
 }
index e33de75..565d3d9 100755 (executable)
@@ -33,8 +33,10 @@ import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
 import mir.module.ModuleExc;
 import mir.module.ModuleFailure;
-import mir.storage.StorageObject;
 import mir.util.JDBCStringRoutines;
+import mir.entity.Entity;
+import mir.entity.EntityList;
+import mircoders.storage.DatabaseLanguage;
 
 /**
  * Title:        mir - another content management system
@@ -48,11 +50,8 @@ import mir.util.JDBCStringRoutines;
 public class ModuleLanguage extends AbstractModule {
   static LoggerWrapper logger = new LoggerWrapper("Module.Language");
 
-  public ModuleLanguage (StorageObject theStorage)     {
-    if (theStorage == null)
-      logger.warn("ModuleLanguage -- StorageObject was null!");
-
-    this.storage = theStorage;
+  public ModuleLanguage ()     {
+    super(DatabaseLanguage.getInstance());
   }
 
   public String languageIdForCode(String aCode) throws ModuleExc, ModuleFailure {
@@ -63,4 +62,19 @@ public class ModuleLanguage extends AbstractModule {
       throw new ModuleFailure(t);
     }
   }
+
+  public Entity languageForCode(String aCode) throws ModuleExc, ModuleFailure {
+    try {
+      EntityList list = storage.selectByFieldValue("code", aCode);
+      if (list.size()>0) {
+        return list.elementAt(0);
+      }
+      else {
+        throw new ModuleExc("No language found for code " + aCode);
+      }
+    }
+    catch (Throwable t) {
+      throw new ModuleFailure(t);
+    }
+  }
 }
\ No newline at end of file
index 8a75c37..19850a5 100755 (executable)
 
 package mircoders.module;
 
-import java.util.List;
-
 import mir.entity.Entity;
 import mir.entity.EntityList;
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
-import mir.module.ModuleExc;
-import mir.module.ModuleFailure;
-import mir.storage.StorageObject;
 import mir.util.JDBCStringRoutines;
 import mir.util.StringRoutines;
 import mircoders.storage.DatabaseMediaType;
 
+import java.util.List;
+
 public class ModuleMediaType extends AbstractModule {
   static LoggerWrapper logger = new LoggerWrapper("Module.Content");
 
   public ModuleMediaType() {
-    this (DatabaseMediaType.getInstance());
+    super(DatabaseMediaType.getInstance());
   }
 
-  public ModuleMediaType(StorageObject aStorage) {
-    this.storage = aStorage;
-  }
-
-  public Entity findMediaTypeForMimeType(String aMimeType) throws ModuleExc, ModuleFailure {
+  public Entity findMediaTypeForMimeType(String aMimeType) {
     List contentTypeParts = StringRoutines.splitString(aMimeType, "/");
 
     if (contentTypeParts.size()!=2) {
-      throw new InvalidMimeTypeExc("Invalid mimetype: " + aMimeType, aMimeType);
+      return null;
     }
     String mimeTypeMajor = (String) contentTypeParts.get(0);
 
@@ -69,34 +62,20 @@ public class ModuleMediaType extends AbstractModule {
       mediaTypes = DatabaseMediaType.getInstance().selectByWhereClause("mime_type = '"+JDBCStringRoutines.escapeStringLiteral(mimeTypeMajor+"/*")+"'");
     }
     if (mediaTypes.size() == 0) {
-      throw new UnsupportedMimeTypeExc("Unsupported mimetype: " + aMimeType, aMimeType);
+      return null;
     }
 
     return (Entity) mediaTypes.elementAt(0);
   }
 
-  public static class MimeTypeExc extends ModuleExc {
-    private String mimeType;
-
-    public MimeTypeExc(String aMessage, String aMimeType) {
-      super (aMessage);
-      mimeType = aMimeType;
-    }
-
-    public String getMimeType() {
-      return mimeType;
-    }
-  }
+  public Entity findMediaTypeForExtension(String anExtension) {
+    EntityList mediaTypes = DatabaseMediaType.getInstance().selectByWhereClause("name = '"+JDBCStringRoutines.escapeStringLiteral(anExtension)+"'");
 
-  public static class UnsupportedMimeTypeExc extends MimeTypeExc {
-    public UnsupportedMimeTypeExc(String aMessage, String aMimeType) {
-      super(aMessage, aMimeType);
+    if (mediaTypes.size() == 0) {
+      return null;
     }
-  }
-
-  public static class InvalidMimeTypeExc extends MimeTypeExc {
-    public InvalidMimeTypeExc(String aMessage, String aMimeType) {
-      super(aMessage, aMimeType);
+    else {
+      return (Entity) mediaTypes.elementAt(0);
     }
   }
 }
\ No newline at end of file
index fe97a7e..0dfb7de 100755 (executable)
@@ -44,19 +44,15 @@ import mir.module.ModuleExc;
 import mir.module.ModuleFailure;
 import mir.storage.StorageObject;
 import mir.util.JDBCStringRoutines;
+import mircoders.storage.DatabaseMediafolder;
 
-
-public class ModuleMediafolder extends AbstractModule
-{
+public class ModuleMediafolder extends AbstractModule {
   static LoggerWrapper logger = new LoggerWrapper("Module.Mediafolder");
 
-  public ModuleMediafolder(StorageObject aStorage)
-  {
-    if (aStorage == null)
-      logger.warn("ModuleMediafolder: StorageObject was null!");
-
-    storage = aStorage;
+  public ModuleMediafolder() {
+    super(DatabaseMediafolder.getInstance());
   }
+
   public String mediaFolderIdForName(String aName) throws ModuleExc, ModuleFailure {
     try {
       return storage.executeFreeSingleValueSql("select id from media_folder where name = '" + JDBCStringRoutines.escapeStringLiteral(aName) + "'");
index 79def2b..18fdcd3 100755 (executable)
@@ -31,26 +31,12 @@ package mircoders.module;
 
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
-import mir.storage.StorageObject;
+import mircoders.storage.DatabaseMessages;
 
-/**
- * Title: ModuleMessage
- * Description:
- * Copyright:    Copyright (c) 2001
- * Company:      Indymedia
- * @author
- * @version 1.0
- */
-
-
-public class ModuleMessage extends AbstractModule
-{
+public class ModuleMessage extends AbstractModule {
   static LoggerWrapper logger = new LoggerWrapper("Module.Message");
 
-  public ModuleMessage (StorageObject theStorage)
-  {
-    if (theStorage == null) logger.warn("ModuleMessage -- StorageObject was null!");
-
-    this.storage = theStorage;
+  public ModuleMessage () {
+    super(DatabaseMessages.getInstance());
   }
 }
\ No newline at end of file
index f235134..9cc517c 100755 (executable)
  */
 package mircoders.module;
 
-import java.util.Map;
-
-import mir.entity.Entity;
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
-import mir.module.ModuleExc;
-import mir.module.ModuleFailure;
-import mir.storage.StorageObject;
+import mircoders.storage.DatabaseTopics;
 
 public class ModuleTopics extends AbstractModule {
 
   static LoggerWrapper logger = new LoggerWrapper("Module.Topics");
 
-  public ModuleTopics(StorageObject theStorage) {
-    this.storage = theStorage;
+  public ModuleTopics() {
+    super (DatabaseTopics.getInstance());
   }
-
-  /**
-   * Overrides the AbstractModule.set(),
-   * All dependent ContentEntities are set unproduced.
-   *
-   * @param theValues Hash mit Spalte/Wert-Paaren
-   * @return Id des eingef?gten Objekts
-   */
-  public String set(Map theValues) throws ModuleExc, ModuleFailure {
-    try {
-      Entity theEntity = storage.selectById((String) theValues.get("id"));
-      if (theEntity == null) {
-        throw new ModuleExc("No topic with id  " + theValues.get("id") + " found");
-      }
-      theEntity.setFieldValues(theValues);
-      theEntity.update();
-
-      return theEntity.getId();
-    }
-    catch (Throwable e) {
-      throw new ModuleFailure(e);
-    }
-  }
-
 }
index 8eaf59f..49cc431 100755 (executable)
@@ -49,6 +49,6 @@ public class ModuleUploadedMedia extends AbstractModule
   static LoggerWrapper logger = new LoggerWrapper("Module.UploadedMedia");
 
   public ModuleUploadedMedia(StorageObject aStorage) {
-    storage = aStorage;
+    super(aStorage);
   }
 }
\ No newline at end of file
index eaf4ff0..259cb45 100755 (executable)
 
 package mircoders.module;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import mir.entity.EntityList;
 import mir.log.LoggerWrapper;
 import mir.module.AbstractModule;
 import mir.module.ModuleExc;
 import mir.module.ModuleFailure;
-import mir.storage.StorageObject;
 import mir.util.JDBCStringRoutines;
 import mircoders.entity.EntityUsers;
 import mircoders.global.MirGlobal;
+import mircoders.storage.DatabaseUsers;
+
+import java.util.HashMap;
+import java.util.Map;
 
 
 /*
@@ -55,12 +55,8 @@ public class ModuleUsers extends AbstractModule
 {
   static LoggerWrapper logger = new LoggerWrapper("Module.Users");
 
-  public ModuleUsers(StorageObject aStorage)
-  {
-    if (aStorage == null)
-      logger.warn("ModuleUsers(): StorageObject was null!");
-
-    storage = aStorage;
+  public ModuleUsers() {
+    super(DatabaseUsers.getInstance());
   }
 
   /**
@@ -108,7 +104,7 @@ public class ModuleUsers extends AbstractModule
     }
   }
 
-  private Map digestPassword(Map aValues) throws ModuleExc, ModuleFailure {
+  private Map digestPassword(Map aValues) throws ModuleFailure {
     Map result = aValues;
 
     try {
index 3676ddb..4cc74c2 100755 (executable)
@@ -118,12 +118,7 @@ public class PDFGenerator{
 
   public PDFGenerator(ByteArrayOutputStream out){
     logger = new LoggerWrapper("PDFGenerator");
-    try {
-      configuration = MirPropertiesConfiguration.instance();
-    }
-    catch (MirPropertiesConfiguration.PropertiesConfigExc e) {
-      throw new RuntimeException("Can't get configuration: " + e.getMessage());
-    }
+    configuration = MirPropertiesConfiguration.instance();
     localImageDir=configuration.getString("Producer.Image.Path");
 
     try {
index 787923e..3aa63d1 100755 (executable)
@@ -38,9 +38,6 @@ import mir.producer.ProducerFailure;
 import mir.producer.ProducerNode;
 import mir.util.ParameterExpander;
 import mircoders.entity.EntityContent;
-import mircoders.module.ModuleContent;
-import mircoders.storage.DatabaseContent;
-
 
 public class ContentModifyingProducerNode implements ProducerNode {
   private String contentKey;
@@ -60,8 +57,6 @@ public class ContentModifyingProducerNode implements ProducerNode {
     String fieldName;
 
     try {
-      ModuleContent contentModule = new ModuleContent(DatabaseContent.getInstance());
-
       data = ParameterExpander.findValueForKey( aValueMap, contentKey );
 
       if (! (data instanceof EntityAdapter)) {
index 685a2c1..db12ed7 100755 (executable)
@@ -34,6 +34,7 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.Map;
+import java.io.File;
 
 import mir.entity.Entity;
 import mir.entity.adapter.EntityAdapter;
@@ -42,6 +43,7 @@ import mir.misc.StringUtil;
 import mir.producer.ProducerFailure;
 import mir.producer.ProducerNode;
 import mir.util.ParameterExpander;
+import mir.util.FileFunctions;
 import mircoders.entity.EntityContent;
 import mircoders.search.AudioSearchTerm;
 import mircoders.search.ContentSearchTerm;
@@ -63,10 +65,12 @@ import org.apache.lucene.store.FSDirectory;
 public class IndexingProducerNode implements ProducerNode {
   private String contentKey;
   private String indexPath;
+  private File indexBasePath;
 
-  public IndexingProducerNode(String aContentKey, String pathToIndex) {
+  public IndexingProducerNode(File anIndexBasePath, String aContentKey, String pathToIndex) {
     contentKey = aContentKey;
     indexPath = pathToIndex;
+    indexBasePath = anIndexBasePath;
   }
 
   public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger)
@@ -74,14 +78,14 @@ public class IndexingProducerNode implements ProducerNode {
     IndexWriter indexWriter = null;
     Object data;
     Entity entity;
-    String index = null;
     long startTime;
     long endTime;
+    File indexFile = null;
 
     startTime = System.currentTimeMillis();
 
     try {
-      index = ParameterExpander.expandExpression(aValueMap, indexPath);
+      indexFile = FileFunctions.getAbsoluteOrRelativeFile(indexBasePath, ParameterExpander.expandExpression(aValueMap, indexPath));
       data = ParameterExpander.findValueForKey(aValueMap, contentKey);
 
       if (!(data instanceof EntityAdapter)) {
@@ -98,22 +102,19 @@ public class IndexingProducerNode implements ProducerNode {
           entity.getClass().getName() + " adapter", null);
       }
 
-      aLogger.info("Indexing " + (String) entity.getFieldValue("id") + " into " +
-        index);
+      aLogger.info("Indexing " + entity.getFieldValue("id") + " into " +  indexFile.getAbsolutePath());
 
       // create an index here if one did not already exist
-      if (!(IndexReader.indexExists(index))) {
-        aLogger.error("Didn't find existing index, so I'm making one in " +
-          index);
+      if (!(IndexReader.indexExists(indexFile))) {
+        aLogger.error("Didn't find existing index, so I'm making one in " + indexFile.getAbsolutePath());
 
-        IndexWriter indexCreator =
-          new IndexWriter(index, new StandardAnalyzer(), true);
+        IndexWriter indexCreator = new IndexWriter(indexFile, new StandardAnalyzer(), true);
         indexCreator.close();
       }
 
-      IndexUtil.unindexEntity((EntityContent) entity, index);
+      IndexUtil.unindexEntity((EntityContent) entity, indexFile);
 
-      indexWriter = new IndexWriter(index, new StandardAnalyzer(), false);
+      indexWriter = new IndexWriter(indexFile, new StandardAnalyzer(), false);
 
       Document theDoc = new Document();
 
@@ -136,21 +137,21 @@ public class IndexingProducerNode implements ProducerNode {
 
       if (textValue!=null) {
         try {
-          year = Integer.parseInt(textValue.substring(0,4));
-          month = Integer.parseInt(textValue.substring(5,7));
-          day = Integer.parseInt(textValue.substring(8,10));
-         hours = Integer.parseInt(textValue.substring(11,13));
-          minutes = Integer.parseInt(textValue.substring(14,16));
+          year = Integer.parseInt(textValue.substring(0, 4));
+          month = Integer.parseInt(textValue.substring(5, 7));
+          day = Integer.parseInt(textValue.substring(8, 10));
+          hours = Integer.parseInt(textValue.substring(11, 13));
+          minutes = Integer.parseInt(textValue.substring(14, 16));
 
-          calendar.set(year, month-1, day, hours, minutes);
+          calendar.set(year, month - 1, day, hours, minutes);
           date = calendar.getTime();
-         SimpleDateFormat formatter = new SimpleDateFormat ("yyyy.MM.dd hh:mm");
-         formattedDate=formatter.format(date);
+          SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd hh:mm");
+          formattedDate = formatter.format(date);
+        }
+        catch (Throwable t) {
+          aLogger.error("Error while generating content date to index: " + t.getMessage());
+          t.printStackTrace(aLogger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
         }
-       catch (Throwable t){
-         aLogger.error("Error while generating content date to index: " + t.getMessage());
-         t.printStackTrace(aLogger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
-       }
       }
       (new KeywordSearchTerm("webdb_create_formatted", "search_date",
         "webdb_create_formatted", "webdb_create_formatted",
@@ -205,19 +206,23 @@ public class IndexingProducerNode implements ProducerNode {
       if (indexWriter != null) {
         try {
           indexWriter.close();
-        } catch (Throwable t) {
+        }
+        catch (Throwable t) {
           aLogger.warn("Error while closing indexWriter: " + t.getMessage());
         }
       }
 
-      try {
-        FSDirectory theIndexDir = FSDirectory.getDirectory(index, false);
+      if (indexFile!=null) {
+        try {
+          FSDirectory theIndexDir = FSDirectory.getDirectory(indexFile, false);
 
-        if (IndexReader.isLocked(theIndexDir)) {
-          IndexReader.unlock(theIndexDir);
+          if (IndexReader.isLocked(theIndexDir)) {
+            IndexReader.unlock(theIndexDir);
+          }
+        }
+        catch (Throwable t) {
+          aLogger.warn("Error while unlocking index: " + t.getMessage());
         }
-      } catch (Throwable t) {
-        aLogger.warn("Error while unlocking index: " + t.getMessage());
       }
     }
 
diff --git a/source/mircoders/producer/RadicalendarProducerNode.java b/source/mircoders/producer/RadicalendarProducerNode.java
new file mode 100755 (executable)
index 0000000..c01fab3
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mircoders.producer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import mir.log.LoggerWrapper;
+import mir.producer.ProducerFailure;
+import mir.producer.ProducerNode;
+import mir.util.ExceptionFunctions;
+import mir.util.ParameterExpander;
+
+import org.apache.xmlrpc.XmlRpcClient;
+import org.apache.xmlrpc.XmlRpcException;
+
+
+public class RadicalendarProducerNode implements ProducerNode {
+  private String key;
+  private String groupname;
+  private String gmtoffset;
+
+
+    public RadicalendarProducerNode(String aKey, String aGroupName, String aGMTOffset) {
+      key = aKey;
+      groupname = aGroupName;
+      gmtoffset = aGMTOffset;
+    
+  }
+
+  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
+    try {
+      String expandedGroupName = ParameterExpander.expandExpression( aValueMap, groupname);
+      String expandedGMTOffset = ParameterExpander.expandExpression( aValueMap, gmtoffset);
+      
+      HashMap events=new HashMap();
+
+      XmlRpcClient xmlrpc = new XmlRpcClient ("http://radicalendar.org:80/xmlresponderweek.php");
+      Vector params = new Vector ();
+      params.addElement(expandedGroupName+":"+expandedGMTOffset); //(shortname from calendar.getGroups)+gmtoffset in minutes
+      Hashtable result = (Hashtable) xmlrpc.execute ("calendar.getWeek", params);
+    
+
+      
+      ArrayList thisWeekEventsList=new ArrayList();
+
+      ArrayList day_keys=new ArrayList();
+      
+      for (Enumeration e = result.keys() ; e.hasMoreElements() ; ){
+        day_keys.add((String) e.nextElement());
+      }  
+      Collections.sort(day_keys);
+      
+      for(Iterator i = day_keys.iterator(); i.hasNext(); ){
+       Hashtable day = (Hashtable) result.get((String) i.next());
+       ArrayList order_keys = new ArrayList();
+       
+       for (Enumeration ee = day.keys() ; ee.hasMoreElements() ; ){
+         order_keys.add((String) ee.nextElement());
+       }
+       Collections.sort(order_keys);
+         
+       for (Iterator ii = order_keys.iterator(); ii.hasNext();){
+         Hashtable event = (Hashtable) day.get((String) ii.next());
+         thisWeekEventsList.add(event); 
+       }
+      }
+
+
+      ParameterExpander.setValueForKey(
+                                      aValueMap,
+                                      key,
+                                      thisWeekEventsList
+                                      );
+    }   
+    catch (Throwable t) {
+      Throwable s = ExceptionFunctions.traceCauseException(t);
+      aLogger.error("Error while accessing radicalendar: " + s.getClass().getName()+","+ s.getMessage());
+    }
+  }
+}
index 8589f75..371ece7 100755 (executable)
@@ -30,6 +30,7 @@
 package mircoders.producer;
 
 import java.util.Map;
+import java.io.File;
 
 import mir.entity.Entity;
 import mir.entity.adapter.EntityAdapter;
@@ -37,22 +38,25 @@ import mir.log.LoggerWrapper;
 import mir.producer.ProducerFailure;
 import mir.producer.ProducerNode;
 import mir.util.ParameterExpander;
+import mir.util.FileFunctions;
 import mircoders.entity.EntityContent;
 import mircoders.search.IndexUtil;
 
 public class UnIndexingProducerNode implements ProducerNode {
   private String contentKey;
   private String indexPath;
+  private File indexBasePath;
 
-  public UnIndexingProducerNode(String aContentKey, String pathToIndex) {
+  public UnIndexingProducerNode(File anIndexBasePath, String aContentKey, String pathToIndex) {
     contentKey = aContentKey;
     indexPath=pathToIndex;
+    indexBasePath = anIndexBasePath;
   }
 
   public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure {
     Object data;
     Entity entity;
-    String index=null;
+    File indexFile;
 
     long startTime;
     long endTime;
@@ -60,7 +64,8 @@ public class UnIndexingProducerNode implements ProducerNode {
     startTime = System.currentTimeMillis();
 
     try {
-      index = ParameterExpander.expandExpression(aValueMap, indexPath);
+      indexFile = FileFunctions.getAbsoluteOrRelativeFile(indexBasePath, ParameterExpander.expandExpression(aValueMap, indexPath));
+
       data = ParameterExpander.findValueForKey( aValueMap, contentKey );
 
       if (! (data instanceof EntityAdapter)) {
@@ -71,9 +76,9 @@ public class UnIndexingProducerNode implements ProducerNode {
       if (! (entity instanceof EntityContent)) {
         throw new ProducerFailure("UnIndexingProducerNode: value of '"+contentKey+"' is not a content EntityAdapter, but a " + entity.getClass().getName() + " adapter", null);
       }
-      aLogger.info("UnIndexing " + (String) entity.getFieldValue("id") + " out of " + index);
+      aLogger.info("UnIndexing " + entity.getFieldValue("id") + " out of " + indexFile.getAbsolutePath());
 
-      IndexUtil.unindexEntity((EntityContent) entity, index);
+      IndexUtil.unindexEntity((EntityContent) entity, indexFile);
     }
     catch (Throwable t) {
       aLogger.error("Error while unindexing content: " + t.getMessage());
index 1146630..783010e 100755 (executable)
 package mircoders.producer.reader;
 
 import java.util.Map;
+import java.io.File;
 
-import mir.entity.adapter.EntityAdapterModel;
 import mir.producer.ProducerNode;
 import mir.producer.reader.DefaultProducerNodeBuilders;
 import mir.producer.reader.ProducerConfigExc;
 import mir.producer.reader.ProducerNodeBuilderLibrary;
-import mir.util.xml.XMLParserEngine;
-import mir.util.xml.XMLReaderTool;
+import mir.producer.reader.ProducerNodeBuilder;
 import mir.util.xml.XMLParserExc;
+import mir.util.xml.XMLReaderTool;
 import mircoders.producer.ContentMarkingProducerNode;
 import mircoders.producer.ContentModifyingProducerNode;
 import mircoders.producer.IndexingProducerNode;
 import mircoders.producer.MediaGeneratingProducerNode;
 import mircoders.producer.PDFGeneratingProducerNode;
 import mircoders.producer.PDFPreFormattingProducerNode;
+import mircoders.producer.RadicalendarProducerNode;
 import mircoders.producer.UnIndexingProducerNode;
 
 
 public class SupplementalProducerNodeBuilders {
 
-  public static void registerBuilders(ProducerNodeBuilderLibrary aBuilderLibrary, EntityAdapterModel aModel) throws ProducerConfigExc {
+  public static void registerBuilders(ProducerNodeBuilderLibrary aBuilderLibrary, File aBasePath) throws ProducerConfigExc {
     aBuilderLibrary.registerBuilder("ModifyContent", ContentModifyingProducerNodeBuilder.class);
     aBuilderLibrary.registerBuilder("MarkContent", ContentMarkingProducerNodeBuilder.class);
     aBuilderLibrary.registerBuilder("GenerateMedia", MediaGeneratingProducerNodeBuilder.class);
 
-    aBuilderLibrary.registerBuilder("IndexContent",ContentIndexingProducerNodeBuilder.class);
-    aBuilderLibrary.registerBuilder("UnIndexContent",ContentUnIndexingProducerNodeBuilder.class);
+    aBuilderLibrary.registerFactory("IndexContent", new ContentIndexingProducerNodeBuilder.factory(aBasePath));
+    aBuilderLibrary.registerFactory("UnIndexContent", new ContentUnIndexingProducerNodeBuilder.factory(aBasePath));
     aBuilderLibrary.registerBuilder("PDFPreFormat", PDFPreFormattingProducerNodeBuilder.class);
     aBuilderLibrary.registerBuilder("PDFGenerate", PDFGeneratingProducerNodeBuilder.class);
+    aBuilderLibrary.registerBuilder("Radicalendar", RadicalendarProducerNodeBuilder.class);
+//    aBuilderLibrary.registerBuilder("ReportChangedFiles", );
   }
 
   private final static String   MARKER_KEY_ATTRIBUTE = DefaultProducerNodeBuilders.KEY_ATTRIBUTE;
@@ -75,7 +78,7 @@ public class SupplementalProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, MARKER_REQUIRED_ATTRIBUTES, MARKER_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, MARKER_REQUIRED_ATTRIBUTES, MARKER_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(MARKER_KEY_ATTRIBUTE);
     };
@@ -91,23 +94,37 @@ public class SupplementalProducerNodeBuilders {
   private final static String[] INDEXER_SUBNODES = {};
 
   public static class ContentIndexingProducerNodeBuilder extends DefaultProducerNodeBuilders.AbstractProducerNodeBuilder {
-
     private String key;
     private String pathToIndex;
+    private File indexBasePath;
+
+    private static class factory implements ProducerNodeBuilderFactory {
+      private File sourceBasePath;
 
-    public ContentIndexingProducerNodeBuilder() {
+      public factory(File aSourceBasePath) {
+        sourceBasePath = aSourceBasePath;
+      }
+
+      public ProducerNodeBuilder makeBuilder() {
+        return new ContentIndexingProducerNodeBuilder(sourceBasePath);
+      }
+    }
+
+    public ContentIndexingProducerNodeBuilder(File anIndexBasePath) {
       super(INDEXER_SUBNODES);
+
+      indexBasePath = anIndexBasePath;
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, INDEXER_REQUIRED_ATTRIBUTES, INDEXER_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, INDEXER_REQUIRED_ATTRIBUTES, INDEXER_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(INDEXER_KEY_ATTRIBUTE);
       pathToIndex = (String) anAttributes.get(INDEXER_INDEX_ATTRIBUTE);
     };
 
     public ProducerNode constructNode() {
-      return new IndexingProducerNode(key,pathToIndex);
+      return new IndexingProducerNode(indexBasePath, key, pathToIndex);
     };
   }
 
@@ -118,23 +135,38 @@ public class SupplementalProducerNodeBuilders {
   private final static String[] UNINDEXER_SUBNODES = {};
 
   public static class ContentUnIndexingProducerNodeBuilder extends DefaultProducerNodeBuilders.AbstractProducerNodeBuilder {
-
     private String key;
     private String pathToIndex;
 
-    public ContentUnIndexingProducerNodeBuilder() {
+    private File indexBasePath;
+
+    private static class factory implements ProducerNodeBuilderFactory {
+      private File indexBasePath;
+
+      public factory(File aSourceBasePath) {
+        indexBasePath = aSourceBasePath;
+      }
+
+      public ProducerNodeBuilder makeBuilder() {
+        return new ContentUnIndexingProducerNodeBuilder(indexBasePath);
+      }
+    }
+
+    public ContentUnIndexingProducerNodeBuilder(File anIndexBasePath) {
       super(UNINDEXER_SUBNODES);
+
+      indexBasePath = anIndexBasePath;
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, UNINDEXER_REQUIRED_ATTRIBUTES, UNINDEXER_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, UNINDEXER_REQUIRED_ATTRIBUTES, UNINDEXER_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(UNINDEXER_KEY_ATTRIBUTE);
       pathToIndex = (String) anAttributes.get(UNINDEXER_INDEX_ATTRIBUTE);
     };
 
     public ProducerNode constructNode() {
-      return new UnIndexingProducerNode(key,pathToIndex);
+      return new UnIndexingProducerNode(indexBasePath, key,pathToIndex);
     };
   }
 
@@ -156,7 +188,7 @@ public class SupplementalProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, CONTENT_MODIFIER_REQUIRED_ATTRIBUTES, CONTENT_MODIFIER_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, CONTENT_MODIFIER_REQUIRED_ATTRIBUTES, CONTENT_MODIFIER_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(CONTENT_MODIFIER_KEY_ATTRIBUTE);
       field = (String) anAttributes.get(CONTENT_MODIFIER_FIELD_ATTRIBUTE);
@@ -182,7 +214,7 @@ public class SupplementalProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, MEDIA_REQUIRED_ATTRIBUTES, MEDIA_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, MEDIA_REQUIRED_ATTRIBUTES, MEDIA_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(MEDIA_KEY_ATTRIBUTE);
     };
@@ -215,7 +247,7 @@ public class SupplementalProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, MARKER_REQUIRED_ATTRIBUTES, MARKER_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, MARKER_REQUIRED_ATTRIBUTES, MARKER_OPTIONAL_ATTRIBUTES);
 
       key = (String) anAttributes.get(MARKER_KEY_ATTRIBUTE);
       numLinesBetweenImages = (String) anAttributes.get(PDF_NUM_LINES_ATTRIBUTE);
@@ -233,7 +265,6 @@ public class SupplementalProducerNodeBuilders {
   }
 
   public static class PDFGeneratingProducerNodeBuilder extends DefaultProducerNodeBuilders.AbstractProducerNodeBuilder {
-    private final static String   MARKER_KEY_ATTRIBUTE = DefaultProducerNodeBuilders.KEY_ATTRIBUTE;
     private final static String   PDF_GENERATOR_ATTRIBUTE = "generator";
     private final static String   PDF_DESTINATION_ATTRIBUTE = "destination";
     private final static String   PDF_STYLESHEET_ATTRIBUTE = "stylesheet";
@@ -251,7 +282,7 @@ public class SupplementalProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
-      mir.util.xml.XMLReaderTool.checkAttributes(anAttributes, MARKER_REQUIRED_ATTRIBUTES, MARKER_OPTIONAL_ATTRIBUTES);
+      XMLReaderTool.checkAttributes(anAttributes, MARKER_REQUIRED_ATTRIBUTES, MARKER_OPTIONAL_ATTRIBUTES);
 
       generator = (String) anAttributes.get(PDF_GENERATOR_ATTRIBUTE);
       destination = (String) anAttributes.get(PDF_DESTINATION_ATTRIBUTE);
@@ -262,6 +293,77 @@ public class SupplementalProducerNodeBuilders {
       return new PDFGeneratingProducerNode(generator,destination,stylesheet);
     };
   }
+
+    public static class RadicalendarProducerNodeBuilder extends DefaultProducerNodeBuilders.AbstractProducerNodeBuilder {
+       private final static String RC_KEY_ATTRIBUTE = "key";
+       private final static String RC_GROUPNAME_ATTRIBUTE = "groupname";
+       private final static String RC_GMTOFFSET_ATTRIBUTE = "gmtoffset";
+       private final static String[] RC_REQUIRED_ATTRIBUTES = {RC_KEY_ATTRIBUTE,RC_GROUPNAME_ATTRIBUTE,RC_GMTOFFSET_ATTRIBUTE};
+       private final static String[] RC_OPTIONAL_ATTRIBUTES = {};
+       private final static String[] RC_SUBNODES = {};
+       private String key;
+       private String groupname;
+       private String gmtoffset;
+
+       public RadicalendarProducerNodeBuilder() {
+           super(RC_SUBNODES);
+       }
+       
+       public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
+           XMLReaderTool.checkAttributes(anAttributes, RC_REQUIRED_ATTRIBUTES, RC_OPTIONAL_ATTRIBUTES);
+
+           key = (String) anAttributes.get(RC_KEY_ATTRIBUTE);
+           groupname = (String) anAttributes.get(RC_GROUPNAME_ATTRIBUTE);
+           gmtoffset = (String) anAttributes.get(RC_GMTOFFSET_ATTRIBUTE);
+       }
+       
+       public ProducerNode constructNode() {
+           return new RadicalendarProducerNode(key,groupname,gmtoffset);
+       }
+                       
+    }
+    
+
+  /**
+   * Builder for {@link mircoders.producer.ChangedFilesReportingProducerNode}
+   * nodes.
+   */
+/*
+  private static class ChangeReportingProducerNodeBuilder extends DefaultProducerNodeBuilders.AbstractProducerNodeBuilder {
+    private final static String   DESTINATION_FILE_ATTRIBUTE = "reportFile";
+    private final static String   LOCK_FILE_ATTRIBUTE = "lockfile";
+    private final static String   BASE_PATH_ATTRIBUTE = "basepath";
+    private final static String   EXCLUDED_PATHS_ATTRIBUTE = "excludedpaths";
+    private final static String   FLUSH_ATTRIBUTE = "flush";
+    private final static String[] REQUIRED_ATTRIBUTES = {DESTINATION_FILE_ATTRIBUTE};
+    private final static String[] OPTIONAL_ATTRIBUTES = {LOCK_FILE_ATTRIBUTE, BASE_PATH_ATTRIBUTE, EXCLUDED_PATHS_ATTRIBUTE, FLUSH_ATTRIBUTE};
+    private final static String[] SUBNODES = {};
+
+    private String reportFile;
+    private String lockFile;
+    private String basePath;
+    private String excludedPaths;
+    private String flush;
+
+    public ChangeReportingProducerNodeBuilder() {
+      super(SUBNODES);
+    }
+
+    public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLParserExc {
+      XMLReaderTool.checkAttributes(anAttributes, REQUIRED_ATTRIBUTES, OPTIONAL_ATTRIBUTES);
+
+      reportFile = XMLReaderTool.getStringAttributeWithDefault(anAttributes, DESTINATION_FILE_ATTRIBUTE, null);
+      lockFile = XMLReaderTool.getStringAttributeWithDefault(anAttributes, LOCK_FILE_ATTRIBUTE, null);
+      basePath = XMLReaderTool.getStringAttributeWithDefault(anAttributes, BASE_PATH_ATTRIBUTE, "");
+      excludedPaths = XMLReaderTool.getStringAttributeWithDefault(anAttributes, EXCLUDED_PATHS_ATTRIBUTE, "");
+      flush = XMLReaderTool.getStringAttributeWithDefault(anAttributes, FLUSH_ATTRIBUTE, "1");
+    };
+
+    public ProducerNode constructNode() {
+      return new ChangedFilesReportingProducerNode(reportFile, lockFile, basePath, excludedPaths, flush);
+    };
+  }
+*/
 }
 
 
index ffbaec1..3468419 100755 (executable)
 
 package mircoders.search;
 
-import java.util.Map;
+import java.util.Iterator;
+import java.util.Map; 
+import java.util.Vector;
 
 import javax.servlet.http.HttpServletRequest;
 
 import mir.entity.Entity;
-import mir.entity.EntityList;
+import mir.entity.EntityBrowser;
 import mir.storage.StorageObjectFailure;
 import mircoders.entity.EntityContent;
 import mircoders.storage.DatabaseContentToMedia;
+import mircoders.storage.DatabaseAudio;
 
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -49,8 +52,16 @@ public class AudioSearchTerm extends SearchTerm{
   }
 
   public void index(Document doc, Entity entity) throws StorageObjectFailure{
-    EntityList audio = DatabaseContentToMedia.getInstance().getAudio((EntityContent) entity);
-    if (audio != null && audio.size()>0){
+      //    EntityList audio = DatabaseContentToMedia.getInstance().getAudio((EntityContent) entity);
+    Vector extraTables = new Vector();
+    extraTables.add("content_x_media cxm");
+    Iterator audios = new EntityBrowser(
+                                       DatabaseAudio.getInstance(), "i", extraTables,
+                                       "cxm.content_id="+entity.getId()+"and cxm.media_id=i.id",
+                                       "i.id desc", 30, -1, 0);
+
+
+    if (audios != null && audios.hasNext()){
       doc.add(Field.Keyword(matchField,"y"));
     }
   }
index b1fa9ae..275cb44 100755 (executable)
 package mircoders.search;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.Vector;
 import javax.servlet.http.HttpServletRequest;
 
 import mir.entity.Entity;
-import mir.entity.EntityList;
+import mir.entity.EntityBrowser;
 import mir.storage.StorageObjectFailure;
 import mircoders.entity.EntityContent;
-import mircoders.storage.DatabaseContentToMedia;
+import mircoders.entity.EntityImages;
+import mircoders.storage.DatabaseImages;
+
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 
@@ -51,15 +55,25 @@ public class ImagesSearchTerm extends SearchTerm{
   }
 
   public void index(Document doc, Entity entity) throws StorageObjectFailure{
-    EntityList images = DatabaseContentToMedia.getInstance().getImages((EntityContent) entity);
-    if (images != null && images.size()>0){
+    Vector extraTables = new Vector();
+    extraTables.add("content_x_media cxm");
+
+    Iterator images = new EntityBrowser(
+                                       DatabaseImages.getInstance(), "i", extraTables,
+                                       "cxm.content_id="+entity.getId()+"and cxm.media_id=i.id",
+                                       "i.id desc", 30, -1, 0);
+
+
+    if (images != null && images.hasNext()){
       doc.add(Field.Keyword(matchField,"y"));
       String imageURLString = "";
-      for(int k=0;k<images.size();k++){
+      int k=0;
+      while(images.hasNext()){
         if (k != 0){
           imageURLString = imageURLString + ":";
         }
-        imageURLString = imageURLString + (images.elementAt(k)).getFieldValue("icon_path");
+             k++;
+        imageURLString = imageURLString + ((EntityImages) images.next()).getFieldValue("icon_path");
       }
       doc.add(Field.UnIndexed("images",imageURLString));
     }
index 68194bc..55104c5 100755 (executable)
 package mircoders.search;
 
 import java.io.IOException;
+import java.io.File;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.store.FSDirectory;
 import mircoders.entity.EntityContent;
 
+/**
+ * Some utility functions for article (un)indexing
+ */
 public class IndexUtil {
+  /**
+   * Unindexes an article
+   */
   public static void unindexEntity (EntityContent anEntity, String anIndex) throws IOException{
+    unindexEntity(anEntity, new File(anIndex));
+  }
+
+  /**
+   * Unindexes an article
+   */
+  public static void unindexEntity (EntityContent anEntity, File anIndex) throws IOException{
     unindexID(anEntity.getId(), anIndex);
   }
 
-  public static void unindexID (String id,String index) throws IOException{
+  /**
+   * Unindexes an article by article id
+   */
+  public static void unindexID (String id,File index) throws IOException{
     IndexReader indexReader = null;
     try{
       indexReader = IndexReader.open(index);
index 3aff976..60137ce 100755 (executable)
  */
 package mircoders.search;
 
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+
 import mir.entity.Entity;
-import mir.entity.EntityList;
+import mir.entity.EntityBrowser;
 import mir.storage.StorageObjectFailure;
 import mircoders.entity.EntityContent;
-import mircoders.storage.DatabaseContentToMedia;
+import mircoders.storage.DatabaseVideo;
+
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
+
+
 
 
 public class VideoSearchTerm extends SearchTerm {
@@ -46,9 +53,15 @@ public class VideoSearchTerm extends SearchTerm {
   }
 
   public void index(Document doc, Entity entity) throws StorageObjectFailure {
-    EntityList video = DatabaseContentToMedia.getInstance().getVideo((EntityContent) entity);
+    Vector extraTables = new Vector();
+    extraTables.add("content_x_media cxm");
+
+    Iterator videos = new EntityBrowser(
+                                       DatabaseVideo.getInstance(), "i", extraTables,
+                                       "cxm.content_id="+entity.getId()+"and cxm.media_id=i.id",
+                                       "i.id desc", 30, -1, 0);
 
-    if ((video != null) && (video.size() > 0)) {
+    if ((videos != null) && (videos.hasNext())) {
       doc.add(Field.Keyword(matchField, "y"));
     }
   }
index f9f4971..1fa0901 100755 (executable)
@@ -30,6 +30,7 @@
 package mircoders.servlet;\r
 \r
 import java.io.PrintWriter;\r
+import java.io.IOException;\r
 import java.util.Locale;\r
 import java.util.Map;\r
 \r
@@ -51,7 +52,7 @@ public class ServletHelper {
   private static LoggerWrapper logger = new LoggerWrapper("ServletModule.Helper");\r
 \r
   public static Map makeGenerationData(HttpServletRequest aRequest, HttpServletResponse aResponse, Locale[] aLocales) throws ServletModuleExc {\r
-    return makeGenerationData(aRequest, aResponse, aLocales, "bundles.adminlocal", "bundles.admin");\r
+    return makeGenerationData(aRequest, aResponse, aLocales, "etc/bundles/adminlocal", "bundles/admin");\r
   }\r
 \r
   public static Map makeGenerationData(HttpServletRequest aRequest, HttpServletResponse aResponse, Locale[] aLocales, String aBundle) throws ServletModuleExc {\r
@@ -61,7 +62,7 @@ public class ServletHelper {
   public static Map makeGenerationData(HttpServletRequest aRequest, HttpServletResponse aResponse, Locale[] aLocales, String aBundle, String aDefaultBundle) throws ServletModuleExc {\r
     try {\r
       MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();\r
-      Map result=GeneratorHelper.makeBasicGenerationData(aLocales,aBundle,aDefaultBundle);\r
+      Map result = GeneratorHelper.makeBasicGenerationData(aLocales, aBundle, aDefaultBundle);\r
       if (configuration.getString("Mir.Admin.ShowLoggedinUsers").equals("1")) {\r
         result.put("loggedinusers", MirGlobal.getLoggedInUsers());\r
       }\r
@@ -112,11 +113,26 @@ public class ServletHelper {
     }\r
   }\r
 \r
+  public static void generateInfoMessage(HttpServletRequest aRequest, HttpServletResponse aResponse,\r
+      Locale[] aLocales, String aBundle, String aDefaultBundle, String aMessage, String anArgument1, String anArgument2) throws ServletModuleExc {\r
+    Map responseData = makeGenerationData(aRequest, aResponse, aLocales, aBundle, aDefaultBundle);\r
+    responseData.put("message", aMessage);\r
+    responseData.put("argument1", anArgument1);\r
+    responseData.put("argument2", anArgument2);\r
+\r
+    try {\r
+      generateResponse(aResponse.getWriter(), responseData, "infomessage.template");\r
+    }\r
+    catch (IOException e) {\r
+      throw new ServletModuleFailure(e);\r
+    }\r
+  }\r
+\r
   public static void redirect(HttpServletResponse aResponse, String aQuery) throws ServletModuleExc, ServletModuleFailure {\r
     try {\r
       aResponse.sendRedirect(aResponse.encodeRedirectURL(MirPropertiesConfiguration.instance().getString("RootUri") + "/servlet/Mir?"+aQuery));\r
     }\r
-    catch (Throwable t) {\r
+    catch (IOException t) {\r
       throw new ServletModuleFailure("ServletModule.redirect: " +t.getMessage(), t);\r
     }\r
   }\r
index 4882598..e026be6 100755 (executable)
@@ -84,7 +84,7 @@ public class ServletModuleAbuse extends ServletModule {
         String anId, String aType, String anExpression, String aComments,
         String aCommentAction, String anArticleAction, String anErrorMessage) throws ServletModuleExc {
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
 
       responseData.put("id", anId);
       responseData.put("type", aType);
@@ -203,7 +203,7 @@ public class ServletModuleAbuse extends ServletModule {
     URLBuilder urlBuilder = new URLBuilder();
 
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
 
       urlBuilder.setValue("module", "Abuse");
       urlBuilder.setValue("do", "showfilters");
@@ -222,7 +222,7 @@ public class ServletModuleAbuse extends ServletModule {
     URLBuilder urlBuilder = new URLBuilder();
 
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
 
       urlBuilder.setValue("module", "Abuse");
       urlBuilder.setValue("do", "showsettings");
@@ -280,7 +280,7 @@ public class ServletModuleAbuse extends ServletModule {
     URLBuilder urlBuilder = new URLBuilder();
 
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
       urlBuilder.setValue("module", "Abuse");
       urlBuilder.setValue("do", "showlog");
       responseData.put("thisurl", urlBuilder.getQuery());
index ccc81ec..568983b 100755 (executable)
  */
 package mircoders.servlet;
 
-import java.util.Locale;
+import java.io.IOException;
+import java.io.Writer;
 import java.util.Map;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
+import mir.servlet.ServletModuleExc;
 import mir.servlet.ServletModuleFailure;
 import mir.util.CachingRewindableIterator;
 import mir.util.URLBuilder;
@@ -55,10 +56,9 @@ public class ServletModuleAdmin extends ServletModule
 
   public void superusermenu(HttpServletRequest aRequest, HttpServletResponse aResponse) {
     URLBuilder urlBuilder = new URLBuilder();
-    int count;
 
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest));
       urlBuilder.setValue("module", "Admin");
       urlBuilder.setValue("do", "superusermenu");
 
@@ -71,13 +71,50 @@ public class ServletModuleAdmin extends ServletModule
     }
   }
 
+  /**
+   * Servlet handler method to reload the configuration for scripts.
+   * The output will be aimed at shell sripts.
+   */
+  public void reload(HttpServletRequest aRequest, HttpServletResponse aResponse) {
+    String result = "reload successfull";
+
+    try {
+      MirGlobal.reloadConfigurations();
+    }
+    catch (Throwable t) {
+      result = "error occurred while reloading: " +t.toString();
+    }
+
+    try {
+      Writer writer = aResponse.getWriter();
+      writer.write(result);
+    }
+    catch (IOException e) {
+      throw new ServletModuleFailure(e);
+    }
+  }
+
+  /**
+   * Servlet handler method to reload the configuration.
+   */
+  public void reloadconfiguration(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
+    try {
+      MirGlobal.reloadConfigurations();
+       ServletHelper.generateInfoMessage(aRequest, aResponse, getLocales(aRequest),
+           "bundles/admin", "etc/bundles/adminlocal", "reloadSuccessfull", "", "");
+    }
+    catch (Throwable t) {
+      ServletHelper.generateInfoMessage(aRequest, aResponse, getLocales(aRequest),
+           "bundles/admin", "etc/bundles/adminlocal", "reloadFailed", t.toString(), "");
+    }
+  }
+
   public void start(HttpServletRequest aRequest, HttpServletResponse aResponse) {
     String defaultStartTemplate = configuration.getString("Mir.StartTemplate");
-    String sessionUrl = aResponse.encodeURL("");
 
     try {
-      Map mergeData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale(aRequest)}
-          , "bundles.admin", "bundles.adminlocal");
+      Map mergeData = ServletHelper.makeGenerationData(aRequest, aResponse, getLocales(aRequest),
+          "bundles/admin", "etc/bundles/adminlocal");
       mergeData.put("messages",
                     new CachingRewindableIterator(
           new EntityIteratorAdapter("", "webdb_create desc", 10,
index 3073b8b..1a99da2 100755 (executable)
@@ -31,9 +31,7 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleArticleType;
-import mircoders.storage.DatabaseArticleType;
 
 /**
  *
@@ -53,9 +51,8 @@ public class ServletModuleArticleType extends ServletModule
     logger = new LoggerWrapper("ServletModule.ArticleType");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "articleType";
-      mainModule = new ModuleArticleType(DatabaseArticleType.getInstance());
+      mainModule = new ModuleArticleType();
     }
     catch (Exception e) {
       logger.error("Initialization of ServletModuleArticleType failed!: " + e.getMessage());
index fe04cb1..e57cbe7 100755 (executable)
@@ -54,7 +54,6 @@ public class ServletModuleAudio extends ServletModuleUploadedMedia {
     moduleName = "Audio";
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "audio";
       mainModule = new ModuleUploadedMedia(DatabaseAudio.getInstance());
     }
index 3a7a06b..dd4ea8d 100755 (executable)
@@ -55,9 +55,8 @@ public class ServletModuleBreaking extends ServletModule
     logger = new LoggerWrapper("ServletModule.Breaking");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "breakingNews";
-      mainModule = new ModuleBreaking(DatabaseBreaking.getInstance());
+      mainModule = new ModuleBreaking();
     }
     catch (Exception e) {
       logger.error("Initialisation of ServletModuleBreaking failed!: " + e.getMessage());
index de606b0..40cdd78 100755 (executable)
 
 package mircoders.servlet;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import mir.entity.adapter.EntityAdapterModel;
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
@@ -46,17 +37,15 @@ import mir.servlet.ServletModule;
 import mir.servlet.ServletModuleExc;
 import mir.servlet.ServletModuleFailure;
 import mir.servlet.ServletModuleUserExc;
-import mir.util.CachingRewindableIterator;
-import mir.util.HTTPRequestParser;
-import mir.util.JDBCStringRoutines;
-import mir.util.SQLQueryBuilder;
-import mir.util.URLBuilder;
+import mir.util.*;
 import mircoders.entity.EntityComment;
 import mircoders.global.MirGlobal;
 import mircoders.module.ModuleComment;
-import mircoders.module.ModuleContent;
 import mircoders.storage.DatabaseComment;
-import mircoders.storage.DatabaseContent;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
 
 /*
  *  ServletModuleComment - controls navigation for Comments
@@ -67,16 +56,13 @@ import mircoders.storage.DatabaseContent;
 
 public class ServletModuleComment extends ServletModule
 {
-  private ModuleContent  moduleContent;
-
   private static ServletModuleComment instance = new ServletModuleComment();
   public static ServletModule getInstance() { return instance; }
 
   private ServletModuleComment() {
     logger = new LoggerWrapper("ServletModule.Comment");
     try {
-      mainModule = new ModuleComment(DatabaseComment.getInstance());
-      moduleContent = new ModuleContent(DatabaseContent.getInstance());
+      mainModule = new ModuleComment();
     }
     catch (Exception e) {
       logger.error("servletmodule comment could not be initialized:" + e.getMessage());
@@ -122,7 +108,7 @@ public class ServletModuleComment extends ServletModule
         comment = model.makeEntityAdapter("comment", mainModule.getById(anId));
       }
       else {
-        List fields = DatabaseComment.getInstance().getFields();
+        List fields = DatabaseComment.getInstance().getFieldNames();
         responseData.put("new", Boolean.TRUE);
         comment = new HashMap();
         Iterator i = fields.iterator();
@@ -201,7 +187,6 @@ public class ServletModuleComment extends ServletModule
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
     SQLQueryBuilder queryBuilder = new SQLQueryBuilder();
 
-    String queryField = "";
     String searchField = requestParser.getParameter("searchfield");
     String searchText = requestParser.getParameter("searchtext");
     String searchIsPublished = requestParser.getParameter("searchispublished");
@@ -259,12 +244,10 @@ public class ServletModuleComment extends ServletModule
 
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
     URLBuilder urlBuilder = new URLBuilder();
-    EntityAdapterModel model;
     int count;
 
     try {
       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
-      model = MirGlobal.localizer().dataModel().adapterModel();
 
       Object commentList =
           new CachingRewindableIterator(
@@ -333,8 +316,6 @@ public class ServletModuleComment extends ServletModule
 
       Map withValues = getIntersectingValues(aRequest, DatabaseComment.getInstance());
 
-      String content_id = aRequest.getParameter("id");
-
       if (!withValues.containsKey("is_published"))
         withValues.put("is_published","0");
       if (!withValues.containsKey("is_html"))
@@ -349,7 +330,7 @@ public class ServletModuleComment extends ServletModule
       logAdminUsage(aRequest, id, "object modified");
 
       if (returnUrl!=null){
-        redirect(aResponse, returnUrl);
+        ServletHelper.redirect(aResponse, returnUrl);
       }
       else
         editObject(aRequest, aResponse, idParam);
index 0ed1df2..71767a0 100755 (executable)
@@ -31,9 +31,7 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleCommentStatus;
-import mircoders.storage.DatabaseCommentStatus;
 
 
 public class ServletModuleCommentStatus extends ServletModule
@@ -45,9 +43,8 @@ public class ServletModuleCommentStatus extends ServletModule
     logger = new LoggerWrapper("ServletModule.CommentStatus");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "commentStatus";
-      mainModule = new ModuleCommentStatus(DatabaseCommentStatus.getInstance());
+      mainModule = new ModuleCommentStatus();
     }
     catch (Throwable e) {
       logger.error("Initialization of ServletModuleCommentStatus failed!: " + e.getMessage());
index 912df40..5feb152 100755 (executable)
@@ -43,6 +43,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import mir.entity.adapter.EntityAdapterModel;
 import mir.entity.adapter.EntityIteratorAdapter;
+import mir.entity.adapter.EntityAdapter;
 import mir.log.LoggerWrapper;
 import mir.misc.StringUtil;
 import mir.servlet.ServletModule;
@@ -54,19 +55,15 @@ import mir.util.JDBCStringRoutines;
 import mir.util.SQLQueryBuilder;
 import mir.util.StringRoutines;
 import mir.util.URLBuilder;
+import mir.generator.Generator;
 import mircoders.entity.*;
 import mircoders.global.MirGlobal;
 import mircoders.module.ModuleContent;
 import mircoders.storage.DatabaseContent;
 import mircoders.storage.DatabaseContentToTopics;
 
-/*
- *  ServletModuleContent -
- *  deliver html for the article admin form.
- *
- * @version $Id: ServletModuleContent.java,v 1.52.2.14 2004/01/18 17:31:00 zapata Exp $
- * @author rk, mir-coders
- *
+/**
+ * Article admin interface code
  */
 
 public class ServletModuleContent extends ServletModule
@@ -81,7 +78,7 @@ public class ServletModuleContent extends ServletModule
     logger = new LoggerWrapper("ServletModule.Content");
 
     try {
-      contentModule = new ModuleContent(DatabaseContent.getInstance());
+      contentModule = new ModuleContent();
       mainModule = contentModule;
     }
     catch (Throwable e) {
@@ -159,8 +156,7 @@ public class ServletModuleContent extends ServletModule
     editObject(aRequest, aResponse, null);
   }
 
-  public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
-  {
+  public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
     try {
       Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
 
@@ -181,8 +177,6 @@ public class ServletModuleContent extends ServletModule
       String id = mainModule.add(withValues);
       logAdminUsage(aRequest, id, "object added");
 
-      List topics;
-
       DatabaseContentToTopics.getInstance().setTopics(id, aRequest.getParameterValues("to_topic"));
 
       editObject(aRequest, aResponse, id);
@@ -192,8 +186,7 @@ public class ServletModuleContent extends ServletModule
     }
   }
 
-  public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
-  {
+  public void edit(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
     String idParam = aRequest.getParameter("id");
     if (idParam == null)
       throw new ServletModuleExc("Invalid call: id not supplied ");
@@ -204,8 +197,7 @@ public class ServletModuleContent extends ServletModule
    * Attaches media to an article
    *
    */
-  public void attach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
-  {
+  public void attach(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
     String  mediaIdParam = aRequest.getParameter("mid");
     String  articleId = aRequest.getParameter("articleid");
 
@@ -263,9 +255,7 @@ public class ServletModuleContent extends ServletModule
   {
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
 
-    String returnUrl = requestParser.getParameter("returnurl");
-
-    String idParam = aRequest.getParameter("id");
+    String idParam = requestParser.getParameter("id");
     if (idParam == null)
       throw new ServletModuleExc("Wrong call: (id) is missing");
 
@@ -286,9 +276,7 @@ public class ServletModuleContent extends ServletModule
   {
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
 
-    String returnUrl = requestParser.getParameter("returnurl");
-
-    String idParam = aRequest.getParameter("id");
+    String idParam = requestParser.getParameter("id");
     if (idParam == null)
       throw new ServletModuleExc("Wrong call: (id) is missing");
 
@@ -309,9 +297,7 @@ public class ServletModuleContent extends ServletModule
   {
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
 
-    String returnUrl = requestParser.getParameter("returnurl");
-
-    String idParam = aRequest.getParameter("id");
+    String idParam = requestParser.getParameter("id");
     if (idParam == null)
       throw new ServletModuleExc("Wrong call: (id) is missing");
 
@@ -333,9 +319,7 @@ public class ServletModuleContent extends ServletModule
     try {
       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
 
-      String returnUrl = requestParser.getParameter("returnurl");
-
-      String idParam = aRequest.getParameter("id");
+      String idParam = requestParser.getParameter("id");
       if (idParam == null)
         throw new ServletModuleExc("Wrong call: (id) is missing");
 
@@ -344,8 +328,6 @@ public class ServletModuleContent extends ServletModule
 
       Map withValues = getIntersectingValues(aRequest, DatabaseContent.getInstance());
 
-      String content_id = aRequest.getParameter("id");
-
       withValues.put("is_produced", "0");
       if (!withValues.containsKey("is_published"))
         withValues.put("is_published","0");
@@ -407,7 +389,7 @@ public class ServletModuleContent extends ServletModule
         responseData.put("mayUnlock", new Boolean(MirGlobal.accessControl().article().mayUnlockArticle(user, id)));
       }
       else {
-        List fields = DatabaseContent.getInstance().getFields();
+        List fields = DatabaseContent.getInstance().getFieldNames();
         responseData.put("new", Boolean.TRUE);
         article = new HashMap();
         Iterator i = fields.iterator();
@@ -507,13 +489,10 @@ public class ServletModuleContent extends ServletModule
 
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
     URLBuilder urlBuilder = new URLBuilder();
-    EntityAdapterModel model;
     int count;
 
     try {
       Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
-      model = MirGlobal.localizer().dataModel().adapterModel();
-
       Object articleList =
           new CachingRewindableIterator(
             new EntityIteratorAdapter( aWhereClause, anOrderByClause, nrEntitiesPerListPage,
@@ -593,8 +572,7 @@ public class ServletModuleContent extends ServletModule
     }
   }
 
-  public void listchildren(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
-  {
+  public void listchildren(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
     try {
       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
       String articleId = requestParser.getParameter("article_id");
@@ -602,7 +580,7 @@ public class ServletModuleContent extends ServletModule
       if (articleId == null)
         throw new ServletModuleExc("ServletModuleContent.listchildren: article_id not set!");
 
-      returnList(aRequest, aResponse, "to_content = " + articleId, "", 0, null);
+      returnList(aRequest, aResponse, "to_content = " + articleId, "webdb_create desc", 0, null);
     }
     catch (Throwable e) {
       throw new ServletModuleFailure(e);
@@ -612,9 +590,9 @@ public class ServletModuleContent extends ServletModule
   public void setparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
   {
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
-    String articleId = aRequest.getParameter("childid");
-    String parentId  = aRequest.getParameter("id");
-    String returnUrl = aRequest.getParameter("returnurl");
+    String articleId = requestParser.getParameter("childid");
+    String parentId  = requestParser.getParameter("id");
+    String returnUrl = requestParser.getParameter("returnurl");
 
     if (!MirGlobal.accessControl().article().mayEditArticle(ServletHelper.getUser(aRequest), articleId))
       throw new ServletModuleExc("Article has been locked");
@@ -631,7 +609,7 @@ public class ServletModuleContent extends ServletModule
       throw new ServletModuleFailure(e);
     }
 
-    redirect(aResponse, returnUrl);
+    ServletHelper.redirect(aResponse, returnUrl);
   }
 
   public void clearparent(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
@@ -654,6 +632,24 @@ public class ServletModuleContent extends ServletModule
       throw new ServletModuleFailure("ServletModuleContent.clearparent: " + e.getMessage(), e);
     }
 
-    redirect(aResponse, returnUrl);
+    ServletHelper.redirect(aResponse, returnUrl);
+  }
+
+  public void showPreview(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
+    try {
+      HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
+      String articleId = requestParser.getParameter("id");
+      EntityAdapter article = model.makeEntityAdapter("content", mainModule.getById(articleId));
+      String preview = requestParser.getParameterWithDefault("preview", "default");
+
+      Map generationValues = new HashMap();
+      Generator generator =
+          MirGlobal.localizer().adminInterface().prepareArticlePreview(preview, article, generationValues);
+
+      generator.generate(aResponse.getWriter(), generationValues, logger);
+    }
+    catch (Exception e) {
+      throw new ServletModuleFailure(e);
+    }
   }
 }
index 30a4bfb..8354040 100755 (executable)
@@ -36,14 +36,12 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.FilenameFilter;
-import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Vector;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -62,7 +60,7 @@ import mir.util.URLBuilder;
  *  in the config file.
  *
  * @author $Author: zapata $
- * @version $Revision: 1.13.2.6 $ $Date: 2003/12/21 17:50:32 $
+ * @version $Revision: 1.13.2.7 $ $Date: 2004/11/21 22:07:14 $
  *
  */
 
@@ -121,7 +119,7 @@ public class ServletModuleFileEdit extends ServletModule
         String setting = settings[i].trim();
 
         if (setting.length() > 0) {
-          List parts = StringRoutines.splitString(setting, ":");
+          List parts = StringRoutines.splitStringWithEscape(setting, ':', '\\');
           if (parts.size() != 4) {
             logger.error("config error: " + settings[i] + ", 4 parts expected");
           }
@@ -195,30 +193,37 @@ public class ServletModuleFileEdit extends ServletModule
     }
   }
 
+  /**
+   * Called when an edited file is saved by the user
+   */
   public void update(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
   {
     HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
     String filename = requestParser.getParameter("filename");
     String subDirectory = requestParser.getParameter("subdirectory");
-    String text = requestParser.getParameter("text");
+    String text =
+        StringRoutines.performRegularExpressionReplacement(
+            requestParser.getParameter("text"),
+            "\r\n",
+            System.getProperty("line.separator"));
     FileEditDirectory directory = getDirectory(aRequest);
 
     try {
       File f = new File(new File(directory.getRootDirectory(), subDirectory), filename);
 
       if (validateDirectory(directory, f)) {
-        StringReader in = new StringReader(text);
         FileWriter out = new FileWriter(f);
-
-        int c;
-        while ( (c = in.read()) != -1)
-          out.write(c);
-        in.close();
-        out.close();
+        try {
+          out.write(text.toCharArray());
+        }
+        finally {
+          out.close();
+        }
 
         logAdminUsage(aRequest, f.getAbsolutePath(), "object modified");
-
-
+/*
+        MirGlobal.getChangeEngine().getTracker().addChange(f.getCanonicalPath());
+*/
         editFile(directory, filename, subDirectory, aRequest, aResponse);
       }
     }
index d5d32ae..0360630 100755 (executable)
  */
 package mircoders.servlet;
 
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
@@ -47,7 +40,12 @@ import mir.util.HTTPRequestParser;
 import mir.util.JDBCStringRoutines;
 import mircoders.global.MirGlobal;
 import mircoders.module.ModuleContent;
-import mircoders.storage.DatabaseContent;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
 
 /*
  *  ServletModuleHidden - output of so called "censored" articles
@@ -67,7 +65,7 @@ public class ServletModuleHidden extends ServletModule
     logger = new LoggerWrapper("ServletModule.Hidden");
 
     try {
-      mainModule = new ModuleContent(DatabaseContent.getInstance());
+      mainModule = new ModuleContent();
     }
     catch (StorageObjectFailure e) {
       logger.error("initialization of servletmoduleHidden failed: " + e.getMessage());
index bfc301e..0075463 100755 (executable)
@@ -31,14 +31,12 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleImages;
-import mircoders.storage.DatabaseImages;
 
 /*
  *  ServletModuleImages -
  *
- * @version $Id: ServletModuleImages.java,v 1.26.2.3 2003/10/23 14:55:25 rk Exp $
+ * @version $Id: ServletModuleImages.java,v 1.26.2.4 2004/11/21 22:07:14 zapata Exp $
  * @author RK, the mir-coders group
  */
 
@@ -55,9 +53,8 @@ public class ServletModuleImages extends ServletModuleUploadedMedia
     moduleName = "Images";
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "image";
-      mainModule = new ModuleImages(DatabaseImages.getInstance());
+      mainModule = new ModuleImages();
     }
     catch (Throwable e) {
       logger.error("Initialization of ServletModuleImages failed!: " + e.getMessage());
index 235a160..616f3b6 100755 (executable)
@@ -31,9 +31,7 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleLanguage;
-import mircoders.storage.DatabaseLanguage;
 
 /*
  *  ServletModuleLanguage -
@@ -53,9 +51,8 @@ public class ServletModuleLanguage extends ServletModule
     logger = new LoggerWrapper("ServletModule.Language");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "language";
-      mainModule = new ModuleLanguage(DatabaseLanguage.getInstance());
+      mainModule = new ModuleLanguage();
     }
     catch (Throwable e) {
       logger.error("Initialization of ServletModuleLanguage failed: " + e.getMessage());
index d6cd208..39370af 100755 (executable)
  */
 package mircoders.servlet;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import mir.entity.adapter.EntityAdapter;
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
 import mir.servlet.ServletModuleExc;
@@ -45,11 +36,15 @@ import mir.util.StringRoutines;
 import mircoders.entity.EntityComment;
 import mircoders.entity.EntityContent;
 import mircoders.global.MirGlobal;
-import mircoders.localizer.MirAdminInterfaceLocalizer;
 import mircoders.module.ModuleComment;
 import mircoders.module.ModuleContent;
-import mircoders.storage.DatabaseComment;
-import mircoders.storage.DatabaseContent;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
 
 public class ServletModuleLocalizer extends ServletModule {
   private static ServletModuleLocalizer instance = new ServletModuleLocalizer();
@@ -63,8 +58,8 @@ public class ServletModuleLocalizer extends ServletModule {
     try {
       logger = new LoggerWrapper("ServletModule.Localizer");
 
-      contentModule = new ModuleContent(DatabaseContent.getInstance());
-      commentModule = new ModuleComment(DatabaseComment.getInstance());
+      contentModule = new ModuleContent();
+      commentModule = new ModuleComment();
 
       administerOperations = new Vector();
 
@@ -81,8 +76,8 @@ public class ServletModuleLocalizer extends ServletModule {
             }
             else {
               Map entry = new HashMap();
-              entry.put("name", (String) parts.get(0));
-              entry.put("url", (String) parts.get(1));
+              entry.put("name", parts.get(0));
+              entry.put("url", parts.get(1));
               administerOperations.add(entry);
             }
           }
@@ -99,15 +94,12 @@ public class ServletModuleLocalizer extends ServletModule {
    *
    * See also
    * {@link mircoders.localizer.MirAdminInterfaceLocalizer#simpleArticleOperations()}
-   * {@link mircoders.localizer.MirAdminInterfaceLocalizer$MirSimpleEntityOperation()}
    *
    * @param aRequest       The originating request
    * @param anId           The id of the article
    * @param anOperation    The identifier of the operation to perform
    */
   public void performCommentOperation(HttpServletRequest aRequest, String anId, String anOperation) {
-    MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation;
-    EntityAdapter comment;
     EntityComment entity;
 
     try {
@@ -134,7 +126,7 @@ public class ServletModuleLocalizer extends ServletModule {
 
     performCommentOperation(aRequest, commentIdString, operationString);
 
-    redirect(aResponse, returnUrlString);
+    ServletHelper.redirect(aResponse, returnUrlString);
   }
 
   public void commentoperationbatch(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
@@ -161,12 +153,10 @@ public class ServletModuleLocalizer extends ServletModule {
       }
     }
 
-    redirect(aResponse, returnUrlString);
+    ServletHelper.redirect(aResponse, returnUrlString);
   }
 
   public void performArticleOperation(HttpServletRequest aRequest, String anId, String anOperation) {
-    MirAdminInterfaceLocalizer.MirSimpleEntityOperation operation;
-    EntityAdapter article;
     EntityContent entity;
 
     try {
@@ -192,7 +182,7 @@ public class ServletModuleLocalizer extends ServletModule {
     String returnUrlString = aRequest.getParameter("returnurl");
 
     performArticleOperation(aRequest, articleIdString, operationString);
-    redirect(aResponse, returnUrlString);
+    ServletHelper.redirect(aResponse, returnUrlString);
   }
 
   public void articleoperationbatch(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
@@ -219,7 +209,7 @@ public class ServletModuleLocalizer extends ServletModule {
       }
     }
 
-    redirect(aResponse, returnUrlString);
+    ServletHelper.redirect(aResponse, returnUrlString);
   }
 
   public List getAdministerOperations() throws ServletModuleExc {
index ab5a9f7..94007f7 100755 (executable)
@@ -31,7 +31,6 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleMediaType;
 import mircoders.storage.DatabaseMediaType;
 
@@ -44,9 +43,8 @@ public class ServletModuleMediaType extends ServletModule
     logger = new LoggerWrapper("ServletModule.MediaType");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "mediaType";
-      mainModule = new ModuleMediaType(DatabaseMediaType.getInstance());
+      mainModule = new ModuleMediaType();
     }
     catch (Exception e) {
       logger.error("Initialization of ServletModuleArticleType failed!: " + e.getMessage());
index d0195e6..4ca4ae6 100755 (executable)
  */
 package mircoders.servlet;
 
-/**
- *
- */
-
-import java.util.GregorianCalendar;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import mir.log.LoggerWrapper;
 import mir.misc.StringUtil;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleMediafolder;
 import mircoders.storage.DatabaseMediafolder;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.GregorianCalendar;
+import java.util.Map;
+
+/**
+ *
+ */
 public class ServletModuleMediafolder extends ServletModule
 {
   public static ServletModule getInstance() { return instance; }
@@ -56,9 +53,8 @@ public class ServletModuleMediafolder extends ServletModule
     logger = new LoggerWrapper("ServletModule.Mediafolder");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "mediaFolder";
-      mainModule = new ModuleMediafolder(DatabaseMediafolder.getInstance());
+      mainModule = new ModuleMediafolder();
     }
     catch (Throwable t) {
       logger.error("Failed to initialize ServletModuleMediafolder: " + t.toString());
index 31c2246..4850e52 100755 (executable)
  */
 package mircoders.servlet;
 
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
 import mir.servlet.ServletModuleFailure;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleMessage;
 import mircoders.storage.DatabaseMessages;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
 /**
  * Title:       ServletModuleMessage
  * Description:
@@ -61,9 +59,8 @@ public class ServletModuleMessage extends ServletModule
     logger = new LoggerWrapper("ServletModule.Messages");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "internalMessage";
-      mainModule = new ModuleMessage(DatabaseMessages.getInstance());
+      mainModule = new ModuleMessage();
     }
     catch (Throwable e) {
       logger.error("initialization of ServletModuleMessage failed!: " + e.getMessage());
index 63cebcf..bdb0f2e 100755 (executable)
 
 package mircoders.servlet;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.Vector;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
 import gnu.regexp.RE;
 import gnu.regexp.REMatch;
+import mir.bundle.Bundle;
 import mir.entity.Entity;
 import mir.generator.Generator;
 import mir.log.LoggerWrapper;
@@ -61,52 +41,39 @@ import mir.servlet.ServletModule;
 import mir.servlet.ServletModuleExc;
 import mir.servlet.ServletModuleFailure;
 import mir.servlet.ServletModuleUserExc;
-import mir.session.HTTPAdapters;
-import mir.session.Request;
-import mir.session.Session;
-import mir.session.SessionHandler;
-import mir.session.SimpleResponse;
-import mir.session.UploadedFile;
+import mir.session.*;
 import mir.storage.StorageObjectFailure;
-import mir.util.ExceptionFunctions;
-import mir.util.HTTPParsedRequest;
-import mir.util.HTTPRequestParser;
-import mir.util.StringRoutines;
+import mir.util.*;
 import mircoders.entity.EntityComment;
 import mircoders.entity.EntityContent;
 import mircoders.global.CacheKey;
 import mircoders.global.MirGlobal;
 import mircoders.media.MediaUploadProcessor;
+import mircoders.media.UnsupportedMediaTypeExc;
 import mircoders.module.ModuleComment;
 import mircoders.module.ModuleContent;
 import mircoders.module.ModuleMediaType;
+import mircoders.media.UnsupportedMediaTypeExc;
 import mircoders.pdf.PDFGenerator;
-import mircoders.search.AudioSearchTerm;
-import mircoders.search.ContentSearchTerm;
-import mircoders.search.ImagesSearchTerm;
-import mircoders.search.KeywordSearchTerm;
-import mircoders.search.TextSearchTerm;
-import mircoders.search.TopicMatrixSearchTerm;
-import mircoders.search.TopicSearchTerm;
-import mircoders.search.UnIndexedSearchTerm;
-import mircoders.search.VideoSearchTerm;
-import mircoders.storage.DatabaseComment;
-import mircoders.storage.DatabaseContent;
-import mircoders.storage.DatabaseContentToMedia;
-import mircoders.storage.DatabaseContentToTopics;
-import mircoders.storage.DatabaseLanguage;
-import mircoders.storage.DatabaseTopics;
+import mircoders.search.*;
+import mircoders.storage.*;
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.net.smtp.SMTPClient;
 import org.apache.commons.net.smtp.SMTPReply;
 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 import org.apache.lucene.document.Document;
+import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.queryParser.QueryParser;
 import org.apache.lucene.search.Hits;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Searcher;
-import org.apache.struts.util.MessageResources;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.*;
+import java.util.*;
 
 /*
  *  ServletModuleOpenIndy -
@@ -115,7 +82,7 @@ import org.apache.struts.util.MessageResources;
  *    open-postings to the newswire
  *
  * @author mir-coders group
- * @version $Id: ServletModuleOpenIndy.java,v 1.89.2.11 2004/02/08 21:05:03 zapata Exp $
+ * @version $Id: ServletModuleOpenIndy.java,v 1.89.2.12 2004/11/21 22:07:14 zapata Exp $
  *
  */
 
@@ -129,9 +96,11 @@ public class ServletModuleOpenIndy extends ServletModule
   private ModuleContent contentModule;
   private ModuleComment commentModule;
   private String        directOp ="yes";
-  // Singelton / Kontruktor
   private static ServletModuleOpenIndy instance = new ServletModuleOpenIndy();
-  public static ServletModule getInstance() { return instance; }
+
+  public  static ServletModule getInstance() {
+    return instance;
+  }
 
   private ServletModuleOpenIndy() {
     super();
@@ -151,9 +120,9 @@ public class ServletModuleOpenIndy extends ServletModule
       emailAnArticleTemplate = configuration.getString("ServletModule.OpenIndy.MailableArticleTemplate");
       sentMailTemplate = configuration.getString("ServletModule.OpenIndy.SentMailTemplate");
       directOp = configuration.getString("DirectOpenposting").toLowerCase();
-      commentModule = new ModuleComment(DatabaseComment.getInstance());
+      commentModule = new ModuleComment();
       mainModule = commentModule;
-      contentModule = new ModuleContent(DatabaseContent.getInstance());
+      contentModule = new ModuleContent();
       defaultAction = "defaultAction";
     }
     catch (StorageObjectFailure e) {
@@ -420,7 +389,7 @@ public class ServletModuleOpenIndy extends ServletModule
       }
 
       Map withValues = new HashMap();
-      i = DatabaseContent.getInstance().getFields().iterator();
+      i = DatabaseContent.getInstance().getFieldNames().iterator();
       while (i.hasNext()) {
         String field = (String) i.next();
         String value = parsedRequest.getParameter(field);
@@ -501,7 +470,7 @@ public class ServletModuleOpenIndy extends ServletModule
       e.printStackTrace(logger.asPrintWriter(LoggerWrapper.DEBUG_MESSAGE));
       Throwable cause = ExceptionFunctions.traceCauseException(e);
 
-      if (cause instanceof ModuleMediaType.UnsupportedMimeTypeExc) {
+      if (cause instanceof UnsupportedMediaTypeExc) {
         throw new ServletModuleUserExc("media.unsupportedformat", new String[] {});
       }
       throw new ServletModuleFailure(e);
@@ -570,7 +539,7 @@ public class ServletModuleOpenIndy extends ServletModule
 
       SimpleResponse response = new SimpleResponse(
           ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getResponseLocale(aRequest.getSession(), aRequest), getFallbackLocale(aRequest)},
-             "bundles.open"));
+             "etc/bundles/open"));
 
       response.setResponseValue("actionURL", aResponse.encodeURL(MirGlobal.config().getString("RootUri") + "/servlet/OpenMir")+"?"+SESSION_REQUEST_KEY+"="+aRequest.getSession().getId());
 
@@ -791,7 +760,7 @@ public class ServletModuleOpenIndy extends ServletModule
           session.setAttribute("positionInResults", new Integer(newPosition));
         }
         else {
-          String indexPath = configuration.getString("IndexPath");
+          File indexFile = FileFunctions.getAbsoluteOrRelativeFile(configuration.getHome(), configuration.getString("IndexPath"));
 
           String creatorFragment = creatorTerm.makeTerm(req);
           if (creatorFragment != null) {
@@ -838,10 +807,10 @@ public class ServletModuleOpenIndy extends ServletModule
             try {
               Searcher searcher = null;
               try {
-                searcher = new IndexSearcher(indexPath);
+                searcher = new IndexSearcher(IndexReader.open(indexFile));
               }
               catch (IOException e) {
-                logger.debug("Can't open indexPath: " + indexPath);
+                logger.debug("Can't open indexPath: " + indexFile.getAbsolutePath());
                 throw new ServletModuleExc("Problem with Search Index! : " + e.toString());
               }
 
@@ -1111,7 +1080,7 @@ public class ServletModuleOpenIndy extends ServletModule
   public void deliver(PrintWriter anOutputWriter, HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator)
       throws ServletModuleFailure {
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)}, "bundles.open");
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)}, "etc/bundles/open");
       responseData.put("data", aData);
       responseData.put("extra", anExtra);
 
@@ -1131,7 +1100,7 @@ public class ServletModuleOpenIndy extends ServletModule
   public void deliver(PrintWriter anOutputWriter, HttpServletRequest aRequest, HttpServletResponse aResponse, Map aData, Map anExtra, String aGenerator,String aLocaleString)
       throws ServletModuleFailure {
     try {
-      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { new Locale(aLocaleString,""), getFallbackLocale(aRequest)}, "bundles.open");
+      Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { new Locale(aLocaleString,""), getFallbackLocale(aRequest)}, "etc/bundles/open");
       responseData.put("data", aData);
       responseData.put("extra", anExtra);
 
@@ -1170,8 +1139,10 @@ public class ServletModuleOpenIndy extends ServletModule
       logger.warn("user error: " + anException.getMessage());
       Map data = new HashMap();
 
-      MessageResources messages = MessageResources.getMessageResources("bundles.open");
-      data.put("errorstring", messages.getMessage(getLocale(aRequest), anException.getMessage(), anException.getParameters()));
+      Bundle bundle =
+          MirGlobal.getBundleFactory().getBundle("etc/bundles/open", new
+              String[] { getLocale(aRequest).getLanguage() });
+      data.put("errorstring", bundle.getValue(anException.getMessage(), Arrays.asList(anException.getParameters())));
       data.put("date", StringUtil.date2readableDateTime(new GregorianCalendar()));
 
       deliver(out, aRequest, aResponse, data, null, configuration.getString("ServletModule.OpenIndy.UserErrorTemplate"));
index 01d9075..d447c09 100755 (executable)
@@ -32,7 +32,6 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleUploadedMedia;
 import mircoders.storage.DatabaseOther;
 
@@ -59,7 +58,6 @@ public class ServletModuleOtherMedia extends ServletModuleUploadedMedia {
     moduleName = "OtherMedia";
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "otherMedia";
       mainModule = new ModuleUploadedMedia(DatabaseOther.getInstance());
     }
index bac92a1..f6e3b67 100755 (executable)
  */
 package mircoders.servlet;
 
-import java.io.PrintWriter;
 import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Vector;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -47,11 +47,7 @@ import mir.producer.ProducerFactory;
 import mir.servlet.ServletModule;
 import mir.servlet.ServletModuleFailure;
 import mir.util.HTTPRequestParser;
-import mir.util.ResourceBundleGeneratorFunction;
 import mircoders.global.MirGlobal;
-import mircoders.global.ProducerEngine;
-
-import org.apache.struts.util.MessageResources;
 
 public class ServletModuleProducer extends ServletModule
 {
@@ -61,18 +57,6 @@ public class ServletModuleProducer extends ServletModule
   Object comments;
   int totalNrComments;
 
-  void generateResponse(String aGeneratorIdentifier, PrintWriter aWriter, Map aResponseData, Locale aLocale) {
-    Generator generator;
-    try {
-      generator = MirGlobal.localizer().generators().makeAdminGeneratorLibrary().makeGenerator(aGeneratorIdentifier);
-      MirGlobal.localizer().producerAssistant().initializeGenerationValueSet(aResponseData);
-      aResponseData.put( "lang", new ResourceBundleGeneratorFunction( aLocale, MessageResources.getMessageResources("bundles.admin")));
-      generator.generate(aWriter, aResponseData, logger);
-    }
-    catch (Throwable t) {
-      throw new ServletModuleFailure(t);
-    }
-  }
 
   private ServletModuleProducer() {
     super();
@@ -80,39 +64,30 @@ public class ServletModuleProducer extends ServletModule
     defaultAction="showProducerQueueStatus";
   }
 
-  public void showMessage(HttpServletRequest aRequest, HttpServletResponse aResponse, String aMessage, String anArgument1, String anArgument2) {
-    Map responseData;
-    try {
-      responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
-      responseData.put("message", aMessage);
-      responseData.put("argument1", anArgument1);
-      responseData.put("argument2", anArgument2);
-
-      ServletHelper.generateResponse(aResponse.getWriter(), responseData, "infomessage.template");
-    }
-    catch (Throwable t) {
-      throw new ServletModuleFailure(t);
-    }
-  }
-
+  /**
+   *
+   * @param aRequest
+   * @param aResponse
+   */
   public void showProducerQueueStatus(HttpServletRequest aRequest, HttpServletResponse aResponse) {
     Map generationData;
     Generator generator;
     List producersData;
 
     try {
+      // TODO: use ServletHelper
       generator = MirGlobal.localizer().generators().makeAdminGeneratorLibrary().makeGenerator("producerqueue.template");
 
       generationData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)});
       generationData.put( "thisurl", "module=Producer&do=showProducerQueueStatus");
 
       producersData = new Vector();
-      Iterator i = MirGlobal.localizer().producers().factories().iterator();
+      Iterator i = MirGlobal.getProducerEngine().getFactories().iterator();
       while (i.hasNext()) {
         ProducerFactory factory = (ProducerFactory) i.next();
 
         List producerVerbs = new Vector();
-        Iterator j = factory.verbs();
+        Iterator j = factory.verbs().iterator();
         while (j.hasNext()) {
           Map verbData = new HashMap();
           ProducerFactory.ProducerVerb verb = (ProducerFactory.ProducerVerb) j.next();
@@ -130,7 +105,7 @@ public class ServletModuleProducer extends ServletModule
       }
       generationData.put("producers", producersData);
 
-      generationData.put("queue", MirGlobal.producerEngine().getQueueStatus());
+      generationData.put("queue", MirGlobal.getProducerEngine().getQueueStatus());
       generator.generate(aResponse.getWriter(), generationData, logger);
     }
     catch (Throwable t) {
@@ -151,7 +126,7 @@ public class ServletModuleProducer extends ServletModule
         String verbParam = aRequest.getParameter("verb");
 
         try {
-          MirGlobal.producerEngine().addJob(producerParam, verbParam);
+          MirGlobal.getProducerEngine().addJob(producerParam, verbParam);
           out.println("job added");
         }
         catch (Throwable t) {
@@ -164,24 +139,34 @@ public class ServletModuleProducer extends ServletModule
     }
   }
 
+  /**
+   * Servlet action to propduce a preconfigured combination of producers
+   * (e.g. "generate all new")
+   */
   public void producerecipe(HttpServletRequest aRequest, HttpServletResponse aResponse) {
     try {
       String recipe = aRequest.getParameter("recipe");
       MirGlobal.localizer().producers().produceRecipe(recipe);
-      showMessage(aRequest, aResponse, "recipeAddedToQueue", recipe, "");
+
+      ServletHelper.generateInfoMessage(aRequest, aResponse,
+          new Locale[] { getLocale(aRequest), getFallbackLocale(aRequest)},
+           "bundles/admin", "etc/bundles/adminlocal", "recipeAddedToQueue", recipe, "");
     }
     catch (Throwable t) {
       throw new ServletModuleFailure(t);
     }
   }
 
+  /**
+   * Servlet action to enqueue a producer job
+   */
   public void enqueue(HttpServletRequest aRequest, HttpServletResponse aResponse) {
     try {
       if (aRequest.getParameter("producer")!=null) {
         String producerParam = aRequest.getParameter("producer");
         String verbParam = aRequest.getParameter("verb");
 
-        MirGlobal.producerEngine().addJob(producerParam, verbParam);
+        MirGlobal.getProducerEngine().addJob(producerParam, verbParam);
 
         ServletHelper.redirect(aResponse, "Producer", "showProducerQueueStatus");
       }
@@ -196,12 +181,12 @@ public class ServletModuleProducer extends ServletModule
       HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
 
       if (requestParser.getParameter("cancelall") != null) {
-        MirGlobal.producerEngine().cancelAllJobs();
+        MirGlobal.getProducerEngine().cancelAllJobs();
       }
       else {
-        List jobs = new Vector(requestParser.getParameterList("jobid"));
+        List jobs = new ArrayList(requestParser.getParameterList("jobid"));
 
-        MirGlobal.producerEngine().cancelJobs(jobs);
+        MirGlobal.getProducerEngine().cancelJobs(jobs);
       }
       ServletHelper.redirect(aResponse, "Producer", "showProducerQueueStatus");
     }
index 441f33b..e7700d0 100755 (executable)
@@ -32,18 +32,10 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleTopics;
-import mircoders.storage.DatabaseTopics;
 
 /**
  *
- * <p>Title: </p>
- * <p>Description: </p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: </p>
- * @author not attributable
- * @version 1.0
  */
 
 public class ServletModuleTopics extends ServletModule
@@ -56,9 +48,8 @@ public class ServletModuleTopics extends ServletModule
     logger = new LoggerWrapper("ServletModule.Topics");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "topic";
-      mainModule = new ModuleTopics(DatabaseTopics.getInstance());
+      mainModule = new ModuleTopics();
     }
     catch (Throwable e) {
       logger.error("Initialization of ServletModuleTopics failed!: " + e.getMessage());
index 976d76a..58067ea 100755 (executable)
@@ -36,7 +36,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Vector;
+import java.util.ArrayList;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletOutputStream;
@@ -68,7 +68,9 @@ import mircoders.entity.EntityContent;
 import mircoders.entity.EntityUploadedMedia;
 import mircoders.global.MirGlobal;
 import mircoders.media.MediaUploadProcessor;
+import mircoders.media.UnsupportedMediaTypeExc;
 import mircoders.module.ModuleMediaType;
+import mircoders.media.UnsupportedMediaTypeExc;
 import mircoders.storage.DatabaseComment;
 import mircoders.storage.DatabaseContent;
 
@@ -96,12 +98,6 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
 
     definition = "uploadedMedia";
     logger = new LoggerWrapper("ServletModule.UploadedMedia");
-    try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
-    }
-    catch (Throwable t) {
-      throw new ServletModuleFailure(t);
-    }
   }
 
   public void insert(HttpServletRequest aRequest, HttpServletResponse aResponse)
@@ -116,7 +112,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
 
       mediaValues.put("to_publisher", ServletHelper.getUser(aRequest).getId());
 
-      Iterator i = mainModule.getStorageObject().getFields().iterator();
+      Iterator i = mainModule.getStorageObject().getFieldNames().iterator();
       while (i.hasNext()) {
         String field = (String) i.next();
         String value = parsedRequest.getParameter(field);
@@ -124,7 +120,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
           mediaValues.put(field, value);
       }
 
-      List mediaList = new Vector();
+      List mediaList = new ArrayList();
 
       i = parsedRequest.getFiles().iterator();
       while (i.hasNext()) {
@@ -151,7 +147,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
           logAdminUsage(aRequest, id, "object attached to article " + articleid);
         }
 
-        ((ServletModuleContent) ServletModuleContent.getInstance()).editObject(aRequest, aResponse, articleid);
+        (ServletModuleContent.getInstance()).editObject(aRequest, aResponse, articleid);
 
 
         return;
@@ -170,7 +166,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
           logAdminUsage(aRequest, id, "object attached to comment " + commentid);
         }
 
-        ((ServletModuleComment) ServletModuleComment.getInstance()).editObject(aRequest, aResponse, commentid);
+        (ServletModuleComment.getInstance()).editObject(aRequest, aResponse, commentid);
 
         return;
       }
@@ -182,7 +178,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
     catch (Throwable t) {
       Throwable cause = ExceptionFunctions.traceCauseException(t);
 
-      if (cause instanceof ModuleMediaType.UnsupportedMimeTypeExc) {
+      if (cause instanceof UnsupportedMediaTypeExc) {
         throw new ServletModuleUserExc("media.error.unsupportedformat", new String[] {});
       }
       throw new ServletModuleFailure("ServletModuleUploadedMedia.insert: " + t.toString(), t);
@@ -198,7 +194,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
           configuration.getString("TempDir"));
       Map mediaValues = new HashMap();
 
-      Iterator i = mainModule.getStorageObject().getFields().iterator();
+      Iterator i = mainModule.getStorageObject().getFieldNames().iterator();
       while (i.hasNext()) {
         String field = (String) i.next();
         String value = parsedRequest.getParameter(field);
@@ -241,6 +237,8 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
       responseData.put("thisurl", aThisUrl);
       responseData.put("nexturl", aNextUrl);
       responseData.put("prevurl", aPreviousUrl);
+      responseData.put("returnurl", requestParser.getParameter("returnurl"));
+
 
       responseData.put("from", Integer.toString(aFrom));
       responseData.put("count", Integer.toString(aCount));
@@ -290,6 +288,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
       urlBuilder.setValue("searchtext", requestParser.getParameter("searchtext"));
       urlBuilder.setValue("searchispublished", requestParser.getParameter("searchispublished"));
       urlBuilder.setValue("searchmediafolder", requestParser.getParameter("searchmediafolder"));
+      urlBuilder.setValue("returnurl", requestParser.getParameter("returnurl"));
       urlBuilder.setValue("where", aWhereClause);
       urlBuilder.setValue("order", anOrderByClause);
 
@@ -320,7 +319,6 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
 
     SQLQueryBuilder queryBuilder = new SQLQueryBuilder();
 
-    String queryField = "";
     String searchField = requestParser.getParameter("searchfield");
     String searchText = requestParser.getParameter("searchtext");
     String searchIsPublished = requestParser.getParameter("searchispublished");
@@ -368,7 +366,7 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
       int nrMedia = requestParser.getIntegerWithDefault("nrmedia", 1);
       int maxNrMedia=configuration.getInt("ServletModule.OpenIndy.MaxMediaUploadItems", 20);
 
-      List fields = mainModule.getStorageObject().getFields();
+      List fields = mainModule.getStorageObject().getFieldNames();
       Map media = new HashMap();
       Iterator i = fields.iterator();
       while (i.hasNext()) {
@@ -380,14 +378,14 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
       responseData.put("new", Boolean.TRUE);
       responseData.put("articleid", requestParser.getParameter("articleid"));
       responseData.put("commentid", requestParser.getParameter("commentid"));
-      responseData.put("returnurl", null);
+      responseData.put("returnurl", requestParser.getParameter("returnurl"));
 
       if (nrMedia<=0)
         nrMedia=1;
       if (nrMedia>maxNrMedia)
         nrMedia=maxNrMedia;
 
-      List mediaFields = new Vector();
+      List mediaFields = new ArrayList();
       for (int j=0; j<nrMedia; j++)
         mediaFields.add(new Integer(j));
 
@@ -416,11 +414,12 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
         Map responseData = ServletHelper.makeGenerationData(aRequest, aResponse, new Locale[] {getLocale(aRequest), getFallbackLocale(aRequest)});
         EntityAdapter object =
             model.makeEntityAdapter(definition, mainModule.getById(idParam));
+        HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
         responseData.put("uploadedmedia", object);
         responseData.put("new", Boolean.FALSE);
         responseData.put("articleid", null);
         responseData.put("commentid", null);
-        responseData.put("returnurl", null);
+        responseData.put("returnurl", requestParser.getParameter("returnurl"));
         responseData.put("thisurl", null);
 
         responseData.put("edittemplate", editGenerator);
@@ -476,15 +475,12 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
 
 
   /**
-   * @obsolete
-   *
    * @param aRequest
    * @param aResponse
    * @throws ServletModuleExc
    */
   public void getIcon(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
     getThumbnail(aRequest, aResponse);
-
   }
 
   /**
@@ -493,40 +489,43 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
    * @param aResponse
    * @throws ServletModuleExc
    */
-  public void getThumbnail(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc
-  {
-    String idParam = aRequest.getParameter("id");
-    if (idParam!=null && !idParam.equals("")) {
+  public void getThumbnail(HttpServletRequest aRequest, HttpServletResponse aResponse) throws ServletModuleExc {
+    String id = aRequest.getParameter("id");
+
+    if (id!=null && !id.equals("")) {
       try {
-        EntityUploadedMedia ent = (EntityUploadedMedia) mainModule.getById(idParam);
-        Entity mediaType = ent.getMediaType();
+        EntityUploadedMedia mediaEntity = (EntityUploadedMedia) mainModule.getById(id);
+        Entity mediaType = mediaEntity.getMediaType();
         MediaHandler mediaHandler;
 
         mediaHandler = MediaHelper.getHandler(mediaType);
-        InputStream in = mediaHandler.getThumbnail(ent);
+        InputStream thumbnailInputStream = mediaHandler.getThumbnail(mediaEntity);
 
-        if (in==null)
+        if (thumbnailInputStream==null)
           throw new ServletModuleExc("no icon available");
 
-        aResponse.setContentType(mediaHandler.getThumbnailMimeType(ent, mediaType));
-        //important that before calling this aResponse.getWriter was not called first
+        aResponse.setContentType(mediaHandler.getThumbnailMimeType(mediaEntity, mediaType));
+
         ServletOutputStream out = aResponse.getOutputStream();
+        try {
+          int read;
+          byte[] buf = new byte[8 * 1024];
 
-        int read ;
-        byte[] buf = new byte[8 * 1024];
-        while((read = in.read(buf)) != -1) {
-          out.write(buf, 0, read);
+          while ((read = thumbnailInputStream.read(buf)) != -1) {
+            out.write(buf, 0, read);
+          }
+
+          thumbnailInputStream.close();
+        }
+        finally {
+          out.close();
         }
-        in.close();
-        out.close();
       }
-
       catch (Throwable e) {
         logger.error("getIcon: " + e.toString());
       }
     }
     else logger.error("getIcon: id not specified.");
-    // no exception allowed
   }
 
   protected void addExtraData(Map aTarget) throws ServletModuleExc, ServletModuleFailure {
@@ -544,12 +543,12 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
     String idParam = aRequest.getParameter("id");
     if (idParam!=null && !idParam.equals("")) {
       try {
-        EntityUploadedMedia entity = (EntityUploadedMedia) mainModule.getById(idParam);
         // TODO rewrite as relational sql
         ServletModuleContent.getInstance().returnList(
             aRequest,
             aResponse,
-            "exists (select * from content_x_media where content_id=content.id and media_id=" + JDBCStringRoutines.escapeStringLiteral( idParam ) + ")", "", 0);
+            "exists (select * from content_x_media where content_id=content.id and media_id='" +
+                  JDBCStringRoutines.escapeStringLiteral( idParam ) + "')", "", 0);
       }
       catch (Throwable t) {
         throw new ServletModuleFailure(t);
@@ -563,12 +562,11 @@ public abstract class ServletModuleUploadedMedia extends ServletModule {
     String idParam = aRequest.getParameter("id");
     if (idParam!=null && !idParam.equals("")) {
       try {
-        EntityUploadedMedia entity = (EntityUploadedMedia) mainModule.getById(idParam);
         // TODO rewrite as relational sql
         ServletModuleComment.getInstance().returnList(
             aRequest,
             aResponse,
-            "exists (select * from comment_x_media where comment_id=comment.id and media_id=" + JDBCStringRoutines.escapeStringLiteral( idParam ) + ")", "", 0);
+            "exists (select * from comment_x_media where comment_id=comment.id and media_id='" + JDBCStringRoutines.escapeStringLiteral( idParam ) + "')", "", 0);
       }
       catch (Throwable t) {
         throw new ServletModuleFailure(t);
index 28521ab..4bfaadc 100755 (executable)
 
 package mircoders.servlet;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import mir.entity.adapter.EntityAdapterModel;
 import mir.entity.adapter.EntityIteratorAdapter;
 import mir.log.LoggerWrapper;
@@ -54,6 +45,10 @@ import mircoders.global.MirGlobal;
 import mircoders.module.ModuleUsers;
 import mircoders.storage.DatabaseUsers;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
 /**
  *
  *
@@ -69,9 +64,8 @@ public class ServletModuleUsers extends ServletModule
     logger = new LoggerWrapper("ServletModule.Users");
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "user";
-      usersModule = new ModuleUsers(DatabaseUsers.getInstance());
+      usersModule = new ModuleUsers();
       mainModule = usersModule;
     }
     catch (Throwable e) {
@@ -165,7 +159,7 @@ public class ServletModuleUsers extends ServletModule
       logAdminUsage(aRequest, id, "object added");
 
       if (requestParser.hasParameter("returnurl"))
-        redirect(aResponse, requestParser.getParameter("returnurl"));
+        ServletHelper.redirect(aResponse, requestParser.getParameter("returnurl"));
       else
         list(aRequest, aResponse);
     }
@@ -197,7 +191,7 @@ public class ServletModuleUsers extends ServletModule
       logAdminUsage(aRequest, id, "object modified");
 
       if (requestParser.hasParameter("returnurl"))
-        redirect(aResponse, requestParser.getParameter("returnurl"));
+        ServletHelper.redirect(aResponse, requestParser.getParameter("returnurl"));
       else
         list(aRequest, aResponse);
     }
@@ -226,9 +220,9 @@ public class ServletModuleUsers extends ServletModule
       }
 
       if (requestParser.hasParameter("returnurl"))
-        redirect(aResponse, requestParser.getParameter("returnurl"));
+        ServletHelper.redirect(aResponse, requestParser.getParameter("returnurl"));
       else
-        redirect(aResponse, "");
+        ServletHelper.redirect(aResponse, "");
     }
     catch (Throwable e) {
       throw new ServletModuleFailure(e);
@@ -250,9 +244,7 @@ public class ServletModuleUsers extends ServletModule
        int anOffset) throws ServletModuleExc {
 
 // ML: to be deleted, support for 3 extra vars to be added
-    HTTPRequestParser requestParser = new HTTPRequestParser(aRequest);
     URLBuilder urlBuilder = new URLBuilder();
-    EntityAdapterModel model;
     int count;
 
     try {
@@ -326,7 +318,7 @@ public class ServletModuleUsers extends ServletModule
         user = model.makeEntityAdapter("user", mainModule.getById(anId));
       }
       else {
-        List fields = DatabaseUsers.getInstance().getFields();
+        List fields = DatabaseUsers.getInstance().getFieldNames();
         responseData.put("new", Boolean.TRUE);
         user = new HashMap();
         Iterator i = fields.iterator();
index fb07f92..5344273 100755 (executable)
@@ -32,7 +32,6 @@ package mircoders.servlet;
 
 import mir.log.LoggerWrapper;
 import mir.servlet.ServletModule;
-import mircoders.global.MirGlobal;
 import mircoders.module.ModuleUploadedMedia;
 import mircoders.storage.DatabaseVideo;
 
@@ -60,7 +59,6 @@ public class ServletModuleVideo extends ServletModuleUploadedMedia {
     moduleName = "Video";
 
     try {
-      model = MirGlobal.localizer().dataModel().adapterModel();
       definition = "video";
       mainModule = new ModuleUploadedMedia(DatabaseVideo.getInstance());
     }
index 84fff6c..20ea23d 100755 (executable)
@@ -39,8 +39,6 @@ package mircoders.storage;
  * @version 1.0
  */
 
-import java.util.List;
-
 import mir.log.LoggerWrapper;
 import mir.storage.Database;
 import mir.storage.StorageObject;
@@ -49,7 +47,6 @@ import mir.storage.StorageObjectFailure;
 public class DatabaseArticleType extends Database implements StorageObject{
 
   private static DatabaseArticleType instance;
-  private static List articletypePopupData;
 
   public synchronized static DatabaseArticleType getInstance() throws StorageObjectFailure {
     if (instance == null) {
index 98e8f8e..400b3fa 100755 (executable)
@@ -70,16 +70,15 @@ public class DatabaseComment extends Database implements StorageObject{
     Statement stmt = null;
     Connection con = null;
     String sql;
-    int res = 0;
 
-    /** @todo comments and topics should be deleted */
+    /** todo comments and topics should be deleted */
     sql = "delete from " + mainTable + " where to_media=" + id;
     logger.info("DELETE "+ sql);
 
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       stmt = con.createStatement();
-      res = stmt.executeUpdate(sql);
+      stmt.executeUpdate(sql);
     }
     catch (SQLException sqe) {
       new StorageObjectFailure(sqe);
index c71043d..07adcd2 100755 (executable)
@@ -48,7 +48,7 @@ import mircoders.entity.EntityUploadedMedia;
  * <b>implements abstract DB connection to the comment_x_media SQL table
  *
  * @author RK, mir-coders group
- * @version $Id: DatabaseCommentToMedia.java,v 1.3.2.6 2004/01/18 17:31:01 zapata Exp $
+ * @version $Id: DatabaseCommentToMedia.java,v 1.3.2.7 2004/11/21 22:07:14 zapata Exp $
  *
  */
 
@@ -164,7 +164,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       ResultSet rs = executeSql(stmt, sql);
@@ -183,7 +183,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
       sql = "insert into " + mainTable + " (comment_id,media_id) values ("
           + commentId + "," + mediaId[i] + ")";
       try {
-        con = getPooledCon();
+        con = obtainConnection();
         // should be a preparedStatement because is faster
         stmt = con.createStatement();
         int rs = executeUpdate(stmt, sql);
@@ -211,7 +211,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
     String sql = "insert into " + mainTable + " (comment_id,media_id) values ("
         + commentId + "," + mediaId + ")";
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -236,7 +236,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -255,7 +255,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
     sql = "insert into " + mainTable + " (comment_id,media_id) values ("
         + commentId + "," + mediaId + ")";
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -280,7 +280,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -306,7 +306,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -334,7 +334,7 @@ public class DatabaseCommentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
index 8d5e809..53c00f7 100755 (executable)
@@ -83,7 +83,7 @@ public class DatabaseContent extends Database implements StorageObject {
     String sql = "update content set is_produced='0' where " + where;
     logger.debug("set unproduced: "+where);
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       executeUpdate(stmt,sql);
index c99bf76..14a4a53 100755 (executable)
@@ -48,7 +48,7 @@ import mircoders.entity.EntityUploadedMedia;
  * <b>implements abstract DB connection to the content_x_media SQL table
  *
  * @author RK, mir-coders group
- * @version $Id: DatabaseContentToMedia.java,v 1.19.2.5 2004/01/18 17:31:01 zapata Exp $
+ * @version $Id: DatabaseContentToMedia.java,v 1.19.2.6 2004/11/21 22:07:14 zapata Exp $
  *
  */
 
@@ -161,7 +161,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       ResultSet rs = executeSql(stmt, sql);
@@ -180,7 +180,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
       sql = "insert into " + mainTable + " (content_id,media_id) values ("
           + contentId + "," + mediaId[i] + ")";
       try {
-        con = getPooledCon();
+        con = obtainConnection();
         // should be a preparedStatement because is faster
         stmt = con.createStatement();
         int rs = executeUpdate(stmt, sql);
@@ -208,7 +208,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
     String sql = "insert into " + mainTable + " (content_id,media_id) values ("
         + contentId + "," + mediaId + ")";
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -233,7 +233,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -252,7 +252,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
     sql = "insert into " + mainTable + " (content_id,media_id) values ("
         + contentId + "," + mediaId + ")";
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -277,7 +277,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -304,7 +304,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
@@ -332,7 +332,7 @@ public class DatabaseContentToMedia extends Database implements StorageObject{
     Connection con = null;
     Statement stmt = null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
       int rs = executeUpdate(stmt, sql);
index 2ad9fb2..2186c5e 100755 (executable)
@@ -76,8 +76,6 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
 
   /**
    * This class return an EntityList of Topics
-   * @param EntityContent content
-   * @returns EntityList
    */
   public EntityList getTopics(EntityContent content) {
     EntityList returnList=null;
@@ -99,8 +97,7 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
   }
 
   /**
-   * Returns a ArrayList of Integer-Objects from a content-id.
-   * @returns ArrayList
+   * Returns a List of String-Objects from a content-id.
    */
   public List getTopicsOfContent(String contentId)
     throws StorageObjectFailure {
@@ -110,13 +107,14 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
       String sql = "select topic_id from " + mainTable + " where content_id=" + contentId;
       Connection con=null;Statement stmt=null;
       try {
-        con = getPooledCon();
+        con = obtainConnection();
+
         // should be a preparedStatement because is faster
         stmt = con.createStatement();
         ResultSet rs = executeSql(stmt,sql);
         if(rs!=null){
           while(rs.next()){
-            returnList.add(new Integer(rs.getInt("topic_id")));
+            returnList.add(Integer.toString(rs.getInt("topic_id")));
           }
         }
       }
@@ -163,9 +161,9 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
     List currentTopics = getTopicsOfContent(anArticleId);
     logger.debug("New topics = " + newTopics.toString());
     logger.debug("Current topics = " + currentTopics.toString());
-    List topicsToDelete = new Vector(currentTopics);
+    List topicsToDelete = new ArrayList(currentTopics);
     topicsToDelete.removeAll(newTopics);
-    List topicsToAdd = new Vector(newTopics);
+    List topicsToAdd = new ArrayList(newTopics);
     topicsToAdd.removeAll(currentTopics);
     logger.debug("to delete = " + topicsToDelete.toString());
     logger.debug("to add = " + topicsToAdd.toString());
@@ -180,9 +178,9 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
       Connection connection=null;
       Statement statement=null;
       try {
-        connection = getPooledCon();
+        connection = obtainConnection();
         statement = connection.createStatement();
-        int rs = executeUpdate(statement, sql);
+        executeUpdate(statement, sql);
       }
       catch (Exception e) {
         logger.error("-- deleting topics failed");
@@ -205,10 +203,10 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
       Connection connection=null;
       Statement statement=null;
       try {
-        connection = getPooledCon();
+        connection = obtainConnection();
         // should be a preparedStatement because is faster
         statement = connection.createStatement();
-        int rs = executeUpdate(statement, sql);
+        executeUpdate(statement, sql);
       }
       catch (Exception e) {
         logger.error("-- adding topics failed");
@@ -234,10 +232,10 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
 
     Connection con=null;Statement stmt=null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
-      ResultSet rs = executeSql(stmt,sql);
+      executeSql(stmt,sql);
     } catch (Exception e) {
       //theLog.printDebugInfo("-- delete topics failed  ");
     } finally {
@@ -256,10 +254,10 @@ public class DatabaseContentToTopics extends Database implements StorageObject{
 
     Connection con=null;Statement stmt=null;
     try {
-      con = getPooledCon();
+      con = obtainConnection();
       // should be a preparedStatement because is faster
       stmt = con.createStatement();
-      ResultSet rs = executeSql(stmt,sql);
+      executeSql(stmt,sql);
     }
     catch (Exception e) {
       logger.error("-- delete topics failed ");
index ff59dcb..6c08aa3 100755 (executable)
@@ -65,7 +65,7 @@
         <if aShowDelete == "1" || aShowEdit == "1" >
           <td>
             <if aShowDelete>
-            <a class="listcommand" href="${config.actionRoot}?module=${aModuleName}&do=delete&id=${entry.id}">${lang("delete")}</a>
+            <a class="listcommand" href="${config.actionRoot}?module=${aModuleName}&amp;do=delete&amp;id=${entry.id}&amp;okurl=${utility.encodeURI(thisurl)}&amp;cancelurl=${utility.encodeURI(thisurl)}">${lang("delete")}</a>
             </if>
             <if aShowDelete == "1" && aShowEdit == "1">
             | 
 
 
 <comment>extra navigation</comment>
-<function AddOrBack(module_name, module_jumpback, do_jumpback)>
+<function showAddOrBack(anAllowAdd, anAddModule, aBackModule, aBackMethod)>
     <p>
-      <a class="link-box" href="${config.actionRoot}?module=${module_name}&do=add">[+] ${lang("add")}</a> &nbsp;
-      <a class="link-box" href="${config.actionRoot}?module=${module_jumpback}&do=${do_jumpback}">[&lt;] ${lang("back")} </a> &nbsp;
-      <a class="link-box" href="${config.actionRoot}">[&lt;&lt;&lt;] ${lang("head.start")}</a>
+      <if anAllowAdd == "1">
+        <a class="link-box" href="${config.actionRoot}?module=${anAddModule}&do=add">[+] ${lang("add")}</a> &nbsp;
+      </if>
+      <a class="link-box" href="${config.actionRoot}?module=${aBackModule}&do=${aBackMethod}">[&lt;] ${lang("back")} </a> &nbsp;
+<comment>      <a class="link-box" href="${config.actionRoot}">[&lt;&lt;&lt;] ${lang("head.start")}</a></comment>
   </p>
 </function>
 
-<function showAddOrBack(anAllowAdd, anAddModule, aBackModule, aBackMethod, )>
+<function showAddOrBack2(anAllowAdd, anAddModule, aBackUrl)>
     <p>
       <if anAllowAdd == "1">
         <a class="link-box" href="${config.actionRoot}?module=${anAddModule}&do=add">[+] ${lang("add")}</a> &nbsp;
       </if>
-      <a class="link-box" href="${config.actionRoot}?module=${aBackModule}&do=${aBackMethod}">[&lt;] ${lang("back")} </a> &nbsp;
-<comment>      <a class="link-box" href="${config.actionRoot}">[&lt;&lt;&lt;] ${lang("head.start")}</a></comment>
+      <a class="link-box" href="${config.actionRoot}?${aBackUrl}">[&lt;] ${lang("back")} </a> &nbsp;
   </p>
 </function>
 
                   <option value="contents"<if searchfield && searchfield=="content"> selected</if>>${lang("contentsearch.field.contents")}</option>
                   <option value="creator_main_url"<if searchfield && searchfield=="creator_main_url"> selected</if>>${lang("contentsearch.field.creator_main_url")}</option>
                   <option value="creator_email"<if searchfield && searchfield=="creator_email"> selected</if>>${lang("contentsearch.field.creator_email")}</option>
+                  <option value="comment"<if searchfield && searchfield=="comment"> selected</if>>${lang("contentsearch.field.comment")}</option>
                 </select>
             </td>
             <td <if aLayout>class="listrow2"</if>>
 
 
 <comment>functions to show media for an article/comment edit page</comment>
-<function showArticleAttachments(anArticle, aCanEdit)>
-  <call showAttachments(1, anArticle, aCanEdit)>
+<function showArticleAttachments(anArticle, aCanEdit, aReturnUrl)>
+  <call showAttachments(1, anArticle, aCanEdit, aReturnUrl)>
 </function>
 
-<function showCommentAttachments(aComment)>
-  <call showAttachments(0, aComment, "1")>
+<function showCommentAttachments(aComment, aReturnUrl)>
+  <call showAttachments(0, aComment, "1", aReturnUrl)>
 </function>
 
-<function showAttachments(anIsArticle, anObject, aCanEdit)>
+<function showAttachments(anIsArticle, anObject, aCanEdit, aReturnUrl)>
   <if anIsArticle=="1">
     <assign objectKey="articleid">
     <assign objectModule="Content">
       </td>
       <if aCanEdit=="1">
         <td align="left" valign="top" class="listrow2">
-          <a href="${config.actionRoot}?module=Images&do=list&${objectKey}=${anObject.id}">[+] ${lang("content.addimage")}</a> |
-          <a href="${config.actionRoot}?module=Images&do=add&${objectKey}=${anObject.id}">${lang("content.uploadimage")}</a>
+          <a href="${config.actionRoot}?module=Images&amp;do=list&amp;${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">[+] ${lang("content.addimage")}</a> |
+          <a href="${config.actionRoot}?module=Images&amp;do=add&amp;${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("content.uploadimage")}</a>
         </td>
       </if>
     </tr>
     <list anObject.to_all_media_images as m>
       <tr>
       <td align=right valign=top>
-        <a href="${config.actionRoot}?module=Images&do=edit&id=${m["id"]}"><img src="${config.actionRoot}?module=Images&do=getIcon&id=${m["id"]}" alt="edit" border="0"></a>&nbsp;
+        <a href="${config.actionRoot}?module=Images&amp;do=getMedia&amp;id=${m["id"]}&amp;returnurl=${utility.encodeURI(aReturnUrl)}"><img src="${config.actionRoot}?module=Images&amp;do=getIcon&amp;id=${m["id"]}" alt="edit" border="0"></a>&nbsp;
       </td>
       <if aCanEdit=="1">
         <td align="left" valign="top">
-          <a href="${config.actionRoot}?module=${objectModule}&do=dettach&${objectKey}=${anObject.id}&mid=${m["id"]}">[-] ${lang("delete")}</a>
+          <a href="${config.actionRoot}?module=${objectModule}&do=dettach&amp;${objectKey}=${anObject.id}&amp;mid=${m["id"]}">[-] ${lang("deattach")}</a> |
+          <a href="${config.actionRoot}?module=Images&amp;do=edit&amp;id=${m.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("edit")}</a>
         </td>
       </if>
       </tr>
       </td>
       <if aCanEdit=="1">
         <td align="left" valign="top" class="listrow2">
-          <a href="${config.actionRoot}?module=Audio&do=list&${objectKey}=${anObject.id}">[+] ${lang("content.addaudio")}</a> |
-          <a href="${config.actionRoot}?module=Audio&do=add&${objectKey}=${anObject.id}">${lang("content.uploadaudio")}</a>
+          <a href="${config.actionRoot}?module=Audio&do=list&amp;${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">[+] ${lang("content.addaudio")}</a> |
+          <a href="${config.actionRoot}?module=Audio&do=add&amp;${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("content.uploadaudio")}</a>
         </td>
       </if>
     </tr>
     <list anObject.to_all_media_audio as m>
       <tr>
       <td align=right valign=top>
-        <a href="${config.actionRoot}?module=Audio&do=edit&id=${m["id"]}"><img src="${config.docRoot}/img/${m["big_icon"]}" alt="edit" border="0"></a>&nbsp;
+        <a href="${config.actionRoot}?module=Audio&amp;do=getMedia&amp;id=${m["id"]}&amp;returnurl=${utility.encodeURI(aReturnUrl)}"><img src="${config.docRoot}/img/${m["big_icon"]}" alt="edit" border="0"></a>&nbsp;
       </td>
       <if aCanEdit=="1">
         <td align="left" valign="top">
-          <a href="${config.actionRoot}?module=${objectModule}&do=dettach&${objectKey}=${anObject.id}&mid=${m["id"]}">[-] ${lang("delete")}</a>
+          <a href="${config.actionRoot}?module=${objectModule}&amp;do=dettach&${objectKey}=${anObject.id}&mid=${m["id"]}">[-] ${lang("deattach")}</a> |
+          <a href="${config.actionRoot}?module=Audio&amp;do=edit&amp;id=${m.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("edit")}</a>
         </td>
       </if>
       </tr>
       </td>
       <if aCanEdit=="1">
         <td  align="left" valign="top" class="listrow2">
-          <a href="${config.actionRoot}?module=Video&do=list&${objectKey}=${anObject.id}">[+] ${lang("content.addvideo")}</a> |
-          <a href="${config.actionRoot}?module=Video&do=add&${objectKey}=${anObject.id}">${lang("content.uploadvideo")}</a>
+          <a href="${config.actionRoot}?module=Video&amp;do=list&${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">[+] ${lang("content.addvideo")}</a> |
+          <a href="${config.actionRoot}?module=Video&amp;do=add&${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("content.uploadvideo")}</a>
         </td>
       </if>
     </tr>
     <list anObject.to_all_media_video as m>
       <tr>
       <td align=right valign=top>
-        <a href="${config.actionRoot}?module=Video&do=edit&id=${m["id"]}"><img src="${config.docRoot}/img/${m["big_icon"]}" alt="edit" border="0"></a>&nbsp;        
+        <a href="${config.actionRoot}?module=Video&amp;do=getMedia&amp;id=${m["id"]}&amp;returnurl=${utility.encodeURI(aReturnUrl)}"><img src="${config.docRoot}/img/${m["big_icon"]}" alt="edit" border="0"></a>&nbsp;        
       </td>
       <if aCanEdit=="1">
         <td align="left" valign="top">
-          <a href="${config.actionRoot}?module=${objectModule}&do=dettach&${objectKey}=${anObject.id}&mid=${m["id"]}">[-] ${lang("delete")}</a>
+          <a href="${config.actionRoot}?module=${objectModule}&amp;do=dettach&amp;${objectKey}=${anObject.id}&amp;mid=${m["id"]}">[-] ${lang("deattach")}</a> |
+          <a href="${config.actionRoot}?module=Video&amp;do=edit&amp;id=${m.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("edit")}</a>
         </td>
       </if>
       </tr>
       </td>
       <if aCanEdit=="1">
         <td align="left" valign="top" class="listrow2">
-          <a href="${config.actionRoot}?module=OtherMedia&do=list&${objectKey}=${anObject.id}">[+] ${lang("content.addother")}</a> |
-          <a href="${config.actionRoot}?module=OtherMedia&do=add&${objectKey}=${anObject.id}">${lang("content.uploadother")}</a>
+          <a href="${config.actionRoot}?module=OtherMedia&do=list&amp;${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">[+] ${lang("content.addother")}</a> |
+          <a href="${config.actionRoot}?module=OtherMedia&do=add&amp;${objectKey}=${anObject.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("content.uploadother")}</a>
         </td>
       </if>
     </tr>
     <list anObject.to_all_media_other as m>
       <tr>
       <td align=right valign=top">
-      <a href="${config.actionRoot}?module=OtherMedia&do=edit&id=${m["id"]}"><img src="${config.docRoot}/img/${m["big_icon"]}" alt="edit" border="0"></a>&nbsp;  
+      <a href="${config.actionRoot}?module=OtherMedia&amp;do=getMedia&amp;id=${m["id"]}&amp;returnurl=${utility.encodeURI(aReturnUrl)}"><img src="${config.docRoot}/img/${m["big_icon"]}" alt="edit" border="0"></a>&nbsp;  
       </td>
       <if aCanEdit=="1">
         <td align="left" valign="top">
-          <a href="${config.actionRoot}?module=${objectModule}&do=dettach&${objectKey}=${anObject.id}&mid=${m["id"]}">[-] ${lang("delete")}</a>
+          <a href="${config.actionRoot}?module=${objectModule}&amp;do=dettach&amp;${objectKey}=${anObject.id}&mid=${m["id"]}">[-] ${lang("deattach")}</a> |
+          <a href="${config.actionRoot}?module=OtherMedia&amp;do=edit&amp;id=${m.id}&amp;returnurl=${utility.encodeURI(aReturnUrl)}">${lang("edit")}</a>
         </td>
       </if>
       </tr>
index 70ec3e1..de87ba3 100755 (executable)
 </function>
 
 <function MediaList (module)>
+    <if returnurl>
+      <call showAddOrBack2("1", module, returnurl)>
+    <else>
+      <call showAddOrBack("1", module, "Admin", "start")>
+    </if>
 
-  <call showAddOrBack("1", module, "Admin", "start")>
     <if medialist>
       <call showPrevNextLinks(prevurl, nexturl, "left")>
 
       </table>
       
       <call showPrevNextLinks(prevurl, nexturl, "left")>
-      <call showAddOrBack("1", module, "Admin", "start")>
+
+      <if returnurl>
+        <call showAddOrBack2("1", module, returnurl)>
+      <else>
+        <call showAddOrBack("1", module, "Admin", "start")>
+      </if>
   
     <else>
       <P align="center">${lang("no_matches_found")}</p>
index 6b1c7a6..1fecf8e 100755 (executable)
           <call showButton(
             "module=Comment&do=articlecomments&articleid="+comment.to_content.id+"&returnurl="+utility.encodeURI(thisurl),
             lang("comment.allcomments"))>
+           <comment>
           <call showAbsoluteLinkButton(
             comment.publicurl,
             lang("preview"))>
+           </comment>
         </if>
 
         <list comment.operations as op>
 
 <tr>
 <td align="left" valign="top">
-<call showCommentAttachments(comment)>
+<call showCommentAttachments(comment, thisurl)>
 </td>
 </tr>
 </table>
index 38ec726..426dc01 100755 (executable)
@@ -37,6 +37,7 @@
         <option value="description"<if searchfield=="description"> selected</if>>${lang("commentsearch.field.description")}</option>
         <option value="main_url"<if searchfield=="main_url"> selected</if>>${lang("commentsearch.field.main_url")}</option>
         <option value="email"<if searchfield=="email"> selected</if>>${lang("commentsearch.field.email")}</option>
+        <option value="comment"<if searchfield=="comment"> selected</if>>${lang("commentsearch.field.comment")}</option>
       </select>
     </td>
     <td class="listrow2">
               <a href="${config.actionRoot}?module=Content&do=edit&id=${entry.to_content.id}">
               ${lang("edit")}
               </a> |
-              <a href="${entry.publicurl}">
-                ${lang("start.show")}
-              </a> |
               <a href="${config.actionRoot}?module=Comment&do=articlecomments&articleid=${entry.to_content.id}">
                 ${lang("commentlist.allcomments")}
               </a>
         
         <b>${entry.title}</b> (${entry.id})&nbsp;
         <if entry.creator>
-          ${lang("by")}: ${entry.creator}
+          ${lang("by")}: ${utility.encodeHTML(entry.creator)}
         </if>
         <br>
-        ${utility.prettyEncodeHTML(entry.description)}
+        ${utility.prettyEncodeHTML(utility.subString(entry.description, 0, config["Mir.Admin.ListTextLengthLimit"]))}
         
-        <if entry.main_url><br>URL: ${entry.main_url}</if>
+        <if entry.main_url><br>URL: ${utility.encodeHTML(entry.main_url)}</if>
         <br>
-  <!--      <div class="bg-neutral small">-->
         <if config["Mir.Localizer.Admin.ListOperationsFlavor"]=="0">
           <list entry.operations as op>
             [ <a href="${config.actionRoot}?module=Localizer&do=commentoperation&operation=${op}&id=${entry.id}&returnurl=${utility.encodeURI(thisurl + "#" + entry.id)}">${lang("comment.operation."+op)}</a> ]
           </select>
         </if>
         <if entry.operations>&nbsp;|&nbsp;</if>
-        <a href="${config.actionRoot}?module=Comment&do=edit&id=${entry.id}">${lang("edit")}</a>                
-  <!--      </div>-->
+        <a href="${config.actionRoot}?module=Comment&do=edit&id=${entry.id}">${lang("edit")}</a>
+        <if entry.to_all_media_images>IMAGES</if>
       </td>
         
       <td valign="top">
index c75de47..dfe72e5 100755 (executable)
             <call showGETButton(
               "module=Comment&do=articlecomments&articleid="+article.id+"&returnurl="+utility.encodeURI(thisurl),
               lang("content.comments"))>
+              
+            <list article.previews as p>              
+              <call showGETButton(
+                "module=Content&do=showPreview&preview="+p+"&id="+article.id+"&returnurl="+utility.encodeURI(thisurl),
+                lang("content.preview."+p))>
+            </list>
         </td>
         <td align="right" valign="top">
           <if article.is_locked=="1" && article.lockinguser>
     </table>
   </td>
     <td align="right" valign="top">
-      <call showArticleAttachments(article, mayEdit)>
+      <call showArticleAttachments(article, mayEdit, thisurl)>
     </td>
   </tr>
 </table>
index 107a4c4..b89e0aa 100755 (executable)
@@ -94,7 +94,7 @@
           </if>
           <if entry.operations> | </if>
           <a href="${config.actionRoot}?module=Content&do=edit&id=${entry.id}&returnurl=${utility.encodeURI(thisurl)}">${lang("edit")}</a> |
-          <a href="${entry.publicurl}">${lang("preview")}</a> |
+         <comment> <a href="${entry.publicurl}">${lang("preview")}</a> |</comment>
           <a href="${config.actionRoot}?module=Comment&do=articlecomments&articleid=${entry.id}&returnurl=${utility.encodeURI(thisurl)}">${lang("contentlist.comments")}</a> (${entry.commentcount})
         <else>
           <span class="text">
index ba64742..2a9996d 100755 (executable)
@@ -12,7 +12,7 @@
 
     <if entities>
       <call showPrevNextLinks(prevurl, nexturl, "left")>
-      <call EntityTable(entities, ["id","name"], [lang("mediatype.id"), lang("mediatype.name")], from, to, count, "1", "1", module)>
+      <call EntityTable(entities, ["id","name", "mime_type", "classname"], [lang("mediatype.id"), lang("mediatype.name"), lang("mediatype.mimetype"), lang("mediatype.classname")], from, to, count, "1", "1", module)>
       <call showPrevNextLinks(prevurl, nexturl, "left")>
       <call showAddOrBack("1", module, "Admin", "superusermenu")>
     <else>
index 958b6c9..145ef36 100755 (executable)
@@ -27,7 +27,6 @@
       </list>
       <br>  
       <a href="${config.actionRoot}?module=Content&do=list&where=${utility.encodeURI("is_published='f'")}&order=${utility.encodeURI("webdb_create desc")}" >&gt; ${lang("start.content.not_published")}</a><br>
-      <a href="${config.actionRoot}?module=Content&do=list&where=${utility.encodeURI("id in (select content_id from content_x_media, media where media.id=media_id)")}&order=${utility.encodeURI("webdb_create desc")}">&gt; ${lang("start.content.with_media")}</a><br>
       <a href="${config.actionRoot}?module=Content&do=list&where=&order=${utility.encodeURI("webdb_lastchange desc")}">&gt; ${lang("start.content.last_changes")}</a><br>
       <a href="${config.actionRoot}?module=Content&do=list&where=${utility.encodeURI("not (comment is null or comment like '')")}&order=${utility.encodeURI("webdb_create desc")}">&gt; ${lang("start.content.with_comments")}</a><br>
       <br>
index 36d0305..e690901 100755 (executable)
@@ -21,6 +21,7 @@
     &gt; <a href="${config.actionRoot}?module=Users&do=list">${lang("superusermenu.users")}</a><br>
     &gt; <a href="${config.actionRoot}?module=Language&do=list">${lang("superusermenu.languages")}</a><br>
     &gt; <a href="${config.actionRoot}?module=Abuse">${lang("superusermenu.abuse")}</a><br>
+    &gt; <a href="${config.actionRoot}?module=Admin&amp;do=reloadconfiguration">${lang("superusermenu.reload")}</a><br>
     </p>
     </td>
       <td>&nbsp;  </td>
diff --git a/web/produced/img/arrow_down.gif b/web/produced/img/arrow_down.gif
deleted file mode 100755 (executable)
index b2b5e2f..0000000
Binary files a/web/produced/img/arrow_down.gif and /dev/null differ
diff --git a/web/produced/img/audio_big.gif b/web/produced/img/audio_big.gif
deleted file mode 100755 (executable)
index e1473c6..0000000
Binary files a/web/produced/img/audio_big.gif and /dev/null differ
diff --git a/web/produced/img/audio_small.gif b/web/produced/img/audio_small.gif
deleted file mode 100755 (executable)
index 4a2677f..0000000
Binary files a/web/produced/img/audio_small.gif and /dev/null differ
diff --git a/web/produced/img/bashcomp2.gif b/web/produced/img/bashcomp2.gif
deleted file mode 100755 (executable)
index 5288065..0000000
Binary files a/web/produced/img/bashcomp2.gif and /dev/null differ
diff --git a/web/produced/img/cleft.gif b/web/produced/img/cleft.gif
deleted file mode 100755 (executable)
index 5a3f14a..0000000
Binary files a/web/produced/img/cleft.gif and /dev/null differ
diff --git a/web/produced/img/dot.gif b/web/produced/img/dot.gif
deleted file mode 100755 (executable)
index d80b7f4..0000000
Binary files a/web/produced/img/dot.gif and /dev/null differ
diff --git a/web/produced/img/extlink.gif b/web/produced/img/extlink.gif
deleted file mode 100755 (executable)
index 4366ee6..0000000
Binary files a/web/produced/img/extlink.gif and /dev/null differ
diff --git a/web/produced/img/help.gif b/web/produced/img/help.gif
deleted file mode 100755 (executable)
index f177ee2..0000000
Binary files a/web/produced/img/help.gif and /dev/null differ
diff --git a/web/produced/img/intlink.gif b/web/produced/img/intlink.gif
deleted file mode 100755 (executable)
index bc10b45..0000000
Binary files a/web/produced/img/intlink.gif and /dev/null differ
diff --git a/web/produced/img/link_small.gif b/web/produced/img/link_small.gif
deleted file mode 100755 (executable)
index 600a830..0000000
Binary files a/web/produced/img/link_small.gif and /dev/null differ
diff --git a/web/produced/img/logo_small.gif b/web/produced/img/logo_small.gif
deleted file mode 100755 (executable)
index f34786d..0000000
Binary files a/web/produced/img/logo_small.gif and /dev/null differ
diff --git a/web/produced/img/mail_small.gif b/web/produced/img/mail_small.gif
deleted file mode 100755 (executable)
index 13cc859..0000000
Binary files a/web/produced/img/mail_small.gif and /dev/null differ
diff --git a/web/produced/img/maillink.gif b/web/produced/img/maillink.gif
deleted file mode 100755 (executable)
index 1c2e50d..0000000
Binary files a/web/produced/img/maillink.gif and /dev/null differ
diff --git a/web/produced/img/photo_big.gif b/web/produced/img/photo_big.gif
deleted file mode 100755 (executable)
index 1481a4e..0000000
Binary files a/web/produced/img/photo_big.gif and /dev/null differ
diff --git a/web/produced/img/photo_small.gif b/web/produced/img/photo_small.gif
deleted file mode 100755 (executable)
index 5f1796c..0000000
Binary files a/web/produced/img/photo_small.gif and /dev/null differ
diff --git a/web/produced/img/pointgris.gif b/web/produced/img/pointgris.gif
deleted file mode 100755 (executable)
index ef2d09f..0000000
Binary files a/web/produced/img/pointgris.gif and /dev/null differ
diff --git a/web/produced/img/search_icon.gif b/web/produced/img/search_icon.gif
deleted file mode 100755 (executable)
index 5f34ea5..0000000
Binary files a/web/produced/img/search_icon.gif and /dev/null differ
diff --git a/web/produced/img/sp.gif b/web/produced/img/sp.gif
deleted file mode 100755 (executable)
index 35d42e8..0000000
Binary files a/web/produced/img/sp.gif and /dev/null differ
diff --git a/web/produced/img/text_big.gif b/web/produced/img/text_big.gif
deleted file mode 100755 (executable)
index 2a31faa..0000000
Binary files a/web/produced/img/text_big.gif and /dev/null differ
diff --git a/web/produced/img/text_small.gif b/web/produced/img/text_small.gif
deleted file mode 100755 (executable)
index ec24bd6..0000000
Binary files a/web/produced/img/text_small.gif and /dev/null differ
diff --git a/web/produced/img/video_big.gif b/web/produced/img/video_big.gif
deleted file mode 100755 (executable)
index 03a683a..0000000
Binary files a/web/produced/img/video_big.gif and /dev/null differ
diff --git a/web/produced/img/video_small.gif b/web/produced/img/video_small.gif
deleted file mode 100755 (executable)
index d61cd29..0000000
Binary files a/web/produced/img/video_small.gif and /dev/null differ
diff --git a/web/produced/style/formate.css b/web/produced/style/formate.css
deleted file mode 100755 (executable)
index f81ecaa..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-<STYLE TYPE="text/css">   
-
-   <!--
-
-   a:link  {
-
-       color : #006600;
-
-       text-decoration : none;
-
-   }
-
-   
-
-   a:visited  {
-
-       color : #009900;
-
-       text-decoration : none;
-
-   }
-
-   
-
-   a:active  {
-
-       color : White;
-
-       text-decoration : none;
-
-       background-color : #006600;
-
-   }
-
-   
-
-   a:hover  {
-
-       color : White;
-
-       text-decoration : none;
-
-       background-color : #006600;
-
-   }
-
-   
-
-   body,ol,div,td,th,address,blockquote,nobr,form  {
-
-       font-family : Trebuchet MS, Verdana, Arial, Helvetica, sans-serif;
-
-   }
-
-   
-
-   h1,h2,h4  {
-
-       font-family : Trebuchet MS, Verdana, Arial, Helvetica,sans-serif;
-
-   }
-
-   
-
-   h3  {
-
-       font-family : Trebuchet MS, Verdana, Arial, Helvetica, sans-serif;
-
-       font-size : 11pt;
-
-   }
-
-   
-
-   pre  {
-
-       font-family : Courier New, Courier, mono, Arial, Helvetica, sans-serif;
-
-       font-size : 8pt;
-
-   }
-
-   
-
-   ul,li,p,ol,b,i  {
-
-       font-family : Trebuchet MS, Verdana, Arial, Helvetica, sans-serif;
-
-   }
-
-   
-
-   p.small  {
-
-       font-family : Trebuchet MS, Verdana, Arial, Helvetica, sans-serif;
-
-       font-size : 8pt;
-
-   }
-
-   
-
-   p.dir  {
-
-       font-family : Trebuchet MS, Verdana, Arial, Helvetica, sans-serif;
-
-       font-size : 10pt;
-
-       margin-top : 0cm;
-
-       margin-bottom : 0cm;
-
-   }
-
-   
-
-   a.black  {
-
-       color : Black;
-
-   }
-
-   -->
-
-   </STYLE>
-
diff --git a/web/produced/style/mir.css b/web/produced/style/mir.css
deleted file mode 100755 (executable)
index 6c12b85..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-a {  color: #0000CC; text-decoration: underline}
-a:hover {  color: #333333; text-decoration: none}
-td {  font-family: "Times New Roman", Times, serif}
-.small {  font-size: x-small}
-pre {  font-family: "Courier", Courier, serif}