summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCédric Bosdonnat <cedricbosdo@openoffice.org>2009-11-18 16:19:26 +0100
committerCédric Bosdonnat <cedricbosdo@openoffice.org>2009-11-18 16:19:26 +0100
commitdcc93da721d19b4e08e7a4b202186b56d9955ddf (patch)
tree55fca95bd85d611454620f3b10a17976b0838d13
parent15f9a487edc99c9213535c74ff6ea8560cc57df0 (diff)
Started to write a few templates
-rw-r--r--.classpath1
-rw-r--r--langs/cpp/classDef.tpl46
-rw-r--r--langs/cpp/component.tpl10
-rw-r--r--langs/cpp/includes.tpl20
-rw-r--r--langs/cpp/lang.properties3
-rw-r--r--langs/cpp/tools.tpl11
-rw-r--r--langs/java4/lang.properties3
-rw-r--r--langs/java5/lang.properties3
-rw-r--r--libs/freemarker-2.3.15/LICENSE.txt46
-rw-r--r--libs/freemarker-2.3.15/freemarker.jarbin0 -> 879259 bytes
-rw-r--r--src/org/openoffice/tools/LanguageHelper.java63
-rw-r--r--src/org/openoffice/tools/OptionsHelper.java7
-rw-r--r--src/org/openoffice/tools/SkeletonMaker.java109
-rw-r--r--src/org/openoffice/tools/TypeChecker.java129
-rw-r--r--src/org/openoffice/tools/language/Language.java106
-rw-r--r--src/org/openoffice/tools/language/LanguageHelper.java68
-rw-r--r--src/org/openoffice/tools/language/LanguageTemplateLoader.java33
-rw-r--r--src/org/openoffice/tools/tests/LanguageHelperTest.java91
-rw-r--r--src/org/openoffice/tools/types/TypeManager.java2
-rw-r--r--test_langs/uncomplete/lang.properties2
-rw-r--r--test_langs/working/lang.properties2
-rw-r--r--test_langs/working/nested.tpl2
-rw-r--r--test_langs/working/simple.tpl1
23 files changed, 631 insertions, 127 deletions
diff --git a/.classpath b/.classpath
index 5de4cc2..64eb80d 100644
--- a/.classpath
+++ b/.classpath
@@ -7,6 +7,7 @@
<attribute name="javadoc_location" value="jar:platform:/resource/Skeletonmaker/libs/commons-cli-1.2/commons-cli-1.2-javadoc.jar!/"/>
</attributes>
</classpathentry>
+ <classpathentry kind="lib" path="libs/freemarker-2.3.15/freemarker.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/OOo Classes"/>
<classpathentry kind="output" path="bin"/>
diff --git a/langs/cpp/classDef.tpl b/langs/cpp/classDef.tpl
new file mode 100644
index 0000000..fbd3d1b
--- /dev/null
+++ b/langs/cpp/classDef.tpl
@@ -0,0 +1,46 @@
+class ${classname} :
+<#if interfaces?size > 0>
+<#if supportsXComponent>
+ private ::cppu::BaseMutex,
+ public ::cppu::WeakComponentImplHelper${interfaces?size}<
+<#else>
+ public ::cppu::WeakComponentImplHelper${interfaces?size}<
+</#if>
+<#list interfaces as intf>
+<assign propHelperNext = !intf_has_next && propertyHelper?length > 0>
+ ${scopedCppName intf.name true}${intf_has_next?string( ",", ">" )}${propHelperNext?string( ",", "" )}
+</#list>
+<#/if>
+<#if propertyHelper?length > 0>
+ public ::cppu::PropertySetMixin<${scopedCppName( propertyHelper, true )}>
+</#if>
+{
+public:
+ explicit ${classname} (css::uno::Reference< css::uno::XComponentContext > const & context);
+
+<#list interfaces as intf>
+ <@printMethods intf/>
+</#list>
+
+private:
+ ${classname}(const ${classname} &); // not defined
+ ${classname}& operator=(const ${classname} &); // not defined
+
+ // destructor is private and will be called indirectly by the release call
+ virtual ~${classname}(){}
+
+<#if componentType == "calc-addin">
+ // TODO
+</#if>
+
+<#if supportsXComponent>
+ // overload WeakComponentImplHelperBase::disposing()
+ // This function is called upon disposing the component,
+ // if your component needs special work when it becomes
+ // disposed, do it here.
+ virtual void SAL_CALL disposing();
+
+
+</#if>
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+} \ No newline at end of file
diff --git a/langs/cpp/component.tpl b/langs/cpp/component.tpl
new file mode 100644
index 0000000..3f24a40
--- /dev/null
+++ b/langs/cpp/component.tpl
@@ -0,0 +1,10 @@
+<#include "tools.tpl">
+<#if hasLicense><#include "license.tpl"/></#if>
+
+<#include "includes.tpl"/>
+
+<#include "classDef.tpl"/>
+
+<#include "classImpl.tpl"/>
+
+<#include "registrationHelper.tpl"/> \ No newline at end of file
diff --git a/langs/cpp/includes.tpl b/langs/cpp/includes.tpl
new file mode 100644
index 0000000..33ee1e1
--- /dev/null
+++ b/langs/cpp/includes.tpl
@@ -0,0 +1,20 @@
+#include "sal/config.h"
+<#if serviceObject>
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+<#else>
+#include "com/sun/star/uno/XComponentContext.hpp"
+</#if>
+<#if supportsXComponent>
+#include "cppuhelper/compbase${interfaces?size}.hxx"
+#include "cppuhelper/basemutex.hxx"
+<#else>
+#include "cppuhelper/implbase${interfaces?size}.hxx"
+</#if>
+<#if propertyHelper?length > 0>
+#include cppuhelper/propertysetmixin.hxx
+</#if>
+
+<#list interfaces as intf>
+#include "${intf?replace( ".", "/" )}.hpp"
+</#list> \ No newline at end of file
diff --git a/langs/cpp/lang.properties b/langs/cpp/lang.properties
index 4b0c5ed..90ce9a6 100644
--- a/langs/cpp/lang.properties
+++ b/langs/cpp/lang.properties
@@ -1 +1,2 @@
-description = generate output for C++ \ No newline at end of file
+description = generate output for C++
+extension = cxx \ No newline at end of file
diff --git a/langs/cpp/tools.tpl b/langs/cpp/tools.tpl
new file mode 100644
index 0000000..bb7a0cd
--- /dev/null
+++ b/langs/cpp/tools.tpl
@@ -0,0 +1,11 @@
+<#function scopedCppName type shortname=false>
+ <#local name = "::" + type?replace( ".", "::" )>
+ <#if shortname>
+ <local name = name?replace( "::com::sun::star", "css" )
+ </#if>
+ <#return name>
+</#function>
+
+<#macro printMethods intf>
+ // TODO
+</#macro> \ No newline at end of file
diff --git a/langs/java4/lang.properties b/langs/java4/lang.properties
index 485031c..a3fc7b6 100644
--- a/langs/java4/lang.properties
+++ b/langs/java4/lang.properties
@@ -1 +1,2 @@
-description = generate output for Java 1.4 or earlier \ No newline at end of file
+description = generate output for Java 1.4 or earlier
+extension = java \ No newline at end of file
diff --git a/langs/java5/lang.properties b/langs/java5/lang.properties
index 11ce36d..a717975 100644
--- a/langs/java5/lang.properties
+++ b/langs/java5/lang.properties
@@ -1 +1,2 @@
-description = generate output for Java 1.5 or later \ No newline at end of file
+description = generate output for Java 1.5 or later
+extension = java \ No newline at end of file
diff --git a/libs/freemarker-2.3.15/LICENSE.txt b/libs/freemarker-2.3.15/LICENSE.txt
new file mode 100644
index 0000000..a91daf3
--- /dev/null
+++ b/libs/freemarker-2.3.15/LICENSE.txt
@@ -0,0 +1,46 @@
+FreeMarker 1.x was released under the LGPL license. Later, by community
+consensus, we have switched over to a BSD-style license. As of FreeMarker
+2.2pre1, the original author, Benjamin Geer, has relinquished the copyright in
+behalf of Visigoth Software Society. The current copyright holder is the
+Visigoth Software Society.
+
+------------------------------------------------------------------------------
+Copyright (c) 2003 The Visigoth Software Society. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+2. The end-user documentation included with the redistribution, if any, must
+ include the following acknowlegement:
+ "This product includes software developed by the
+ Visigoth Software Society (http://www.visigoths.org/)."
+ Alternately, this acknowlegement may appear in the software itself, if and
+ wherever such third-party acknowlegements normally appear.
+
+3. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
+ project contributors may be used to endorse or promote products derived
+ from this software without prior written permission. For written
+ permission, please contact visigoths@visigoths.org.
+
+4. Products derived from this software may not be called "FreeMarker" or
+ "Visigoth" nor may "FreeMarker" or "Visigoth" appear in their names
+ without prior written permission of the Visigoth Software Society.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+VISIGOTH SOFTWARE SOCIETY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------------
+
+This software consists of voluntary contributions made by many individuals on
+behalf of the Visigoth Software Society. For more information on the Visigoth
+Software Society, please see http://www.visigoths.org/
diff --git a/libs/freemarker-2.3.15/freemarker.jar b/libs/freemarker-2.3.15/freemarker.jar
new file mode 100644
index 0000000..8b93b17
--- /dev/null
+++ b/libs/freemarker-2.3.15/freemarker.jar
Binary files differ
diff --git a/src/org/openoffice/tools/LanguageHelper.java b/src/org/openoffice/tools/LanguageHelper.java
deleted file mode 100644
index 5a702d8..0000000
--- a/src/org/openoffice/tools/LanguageHelper.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.openoffice.tools;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FilenameFilter;
-import java.net.URISyntaxException;
-import java.util.Properties;
-
-public class LanguageHelper {
-
- private static final String LANGS_DIR = "langs";
- private static final String DESCRIPTION_FILENAME = "lang.properties";
-
- public static String[] getLanguages() {
- File langsDir = getLangsDir();
-
- String[] langs = langsDir.list( new FilenameFilter() {
-
- @Override
- public boolean accept(File pDir, String pName) {
- return !pName.startsWith(".");
- }
- });
-
- return langs;
- }
-
- public static String getDescription( String pLang ) {
- String description = null;
- File langsDir = getLangsDir();
- File langDir = new File( langsDir, pLang );
-
- if ( langDir.isDirectory() ) {
- File descFile = new File( langDir, DESCRIPTION_FILENAME );
- if ( descFile.isFile() && descFile.canRead() ) {
- Properties props = new Properties( );
- FileInputStream in = null;
- try {
- in = new FileInputStream( descFile );
- props.load( in );
- description = props.getProperty( "description" );
- } catch ( Exception e ) {
- } finally {
- try { in.close(); } catch ( Exception e) { };
- }
- }
- }
-
- return description;
- }
-
- private static File getLangsDir( ) {
- File dir = null;
- try {
- File jarFile = new File(LanguageHelper.class.getProtectionDomain()
- .getCodeSource().getLocation().toURI());
- dir = new File( jarFile.getParentFile(), LANGS_DIR );
-
- } catch (URISyntaxException e) {
- }
- return dir;
- }
-}
diff --git a/src/org/openoffice/tools/OptionsHelper.java b/src/org/openoffice/tools/OptionsHelper.java
index 01633d2..c1adcf9 100644
--- a/src/org/openoffice/tools/OptionsHelper.java
+++ b/src/org/openoffice/tools/OptionsHelper.java
@@ -3,6 +3,8 @@ package org.openoffice.tools;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
+import org.openoffice.tools.language.Language;
+import org.openoffice.tools.language.LanguageHelper;
import org.openoffice.tools.options.Command;
import org.openoffice.tools.options.SubCommand;
@@ -25,9 +27,10 @@ public class OptionsHelper {
Options generalOptions = new Options();
OptionGroup langGroup = new OptionGroup();
- String[] langs = LanguageHelper.getLanguages( );
+ String[] langs = LanguageHelper.getLanguagesIds( );
for (String lang : langs) {
- Option langOpt = new Option( lang, false, LanguageHelper.getDescription( lang ) );
+ Language langDef = LanguageHelper.getLanguage( lang );
+ Option langOpt = new Option( lang, false, langDef.getDescription() );
langGroup.addOption( langOpt );
}
langGroup.setRequired( true );
diff --git a/src/org/openoffice/tools/SkeletonMaker.java b/src/org/openoffice/tools/SkeletonMaker.java
index ad319b6..febb932 100644
--- a/src/org/openoffice/tools/SkeletonMaker.java
+++ b/src/org/openoffice/tools/SkeletonMaker.java
@@ -1,67 +1,55 @@
package org.openoffice.tools;
-import java.util.ArrayList;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
+import org.openoffice.tools.language.Language;
+import org.openoffice.tools.language.LanguageHelper;
import org.openoffice.tools.options.Command;
import org.openoffice.tools.options.HelpFormatter;
import org.openoffice.tools.options.SubcommandLine;
import org.openoffice.tools.types.TypeManager;
-import com.sun.star.reflection.XInterfaceAttributeTypeDescription2;
-import com.sun.star.reflection.XPropertyTypeDescription;
+import freemarker.template.Template;
public class SkeletonMaker {
- private static final int MAX_INTERFACES = 12;
-
+ // The file template names
+ public static final String COMPONENT = "component.tpl";
+
public static void generateComponent( CommandLine pArgs ) {
TypeManager manager = null;
+ PrintWriter writer = null;
try {
- // Get the language first
- String lang = getLanguage( pArgs );
-
// Load the types manager
String inifile = pArgs.getOptionValue( "unoinstall" );
manager = new TypeManager( inifile );
manager.initRegistries( pArgs.getOptionValues( "l" ) );
- // Check the types
- String[] types = pArgs.getOptionValues( "t" );
- ArrayList<String> interfaces = new ArrayList<String>();
- ArrayList<String> services = new ArrayList<String>();
- ArrayList<XPropertyTypeDescription> members = new ArrayList<XPropertyTypeDescription>();
-
- // Get the service, interfaces and members from the types
- for (String type : types) {
- manager.checkType( type, services, interfaces, members );
- }
-
- // TODO For ProtocolHandler case, check the frame.ProtocolHandler and frame.XDispatch types
+ // Extract all the informations from the types
+ TypeChecker checker = new TypeChecker( manager );
+ checker.check( pArgs );
- // Check for the property helper
- ArrayList<XInterfaceAttributeTypeDescription2> attributes = new ArrayList<XInterfaceAttributeTypeDescription2>();
- ArrayList<String> propinterfaces = new ArrayList<String>();
- String propertyHelper = manager.checkPropertyHelper( pArgs, services, interfaces, attributes, propinterfaces );
+ // Print everything
+ writer = getWriter( pArgs );
- // Check the default interfaces
- checkDefaultInterfaces( interfaces, services, propertyHelper );
-
- if ( interfaces.size() > MAX_INTERFACES ) {
- throw new DumpException( "The skeletonmaker supports components with 12 interfaces only (limitation of the UNO implementation helpers)!" );
- }
-
- boolean supportXComp = manager.checkXComponentSupport( interfaces );
-
- // TODO Print everything
+ Language lang = getLanguage( pArgs );
+ Template tpl = lang.getTemplate( COMPONENT );
+ tpl.process( checker.getTemplateModel( ), writer );
+ writer.flush();
} catch ( Exception e ) {
e.printStackTrace();
} finally {
+ // Close the file stream if possible
+ try { writer.close(); } catch ( Exception e ) { }
+
// Close the running OOo
if ( manager != null ) {
manager.dispose();
@@ -69,22 +57,47 @@ public class SkeletonMaker {
}
}
- private static void checkDefaultInterfaces(ArrayList<String> pInterfaces,
- ArrayList<String> pServices, String pPropertyHelper) {
+ private static PrintWriter getWriter( CommandLine pArgs ) throws IOException {
+ PrintWriter writer = new PrintWriter( System.out );
+ String outPath = pArgs.getOptionValue( "o" );
+ if ( outPath != null && !outPath.equals( "stdout" ) ) {
+ String implName = pArgs.getOptionValue( "n" ).replace( '.', '/' );
+ Language lang = getLanguage( pArgs );
+ String ext = lang.getExtension();
+
+ String targetPath = getFilenameFromType( outPath, implName, ext );
+
+ File out = new File( targetPath );
+ writer = new PrintWriter( out );
+ }
- if ( pServices.isEmpty() ) {
- pInterfaces.remove( "com.sun.star.lang.XServiceInfo" );
+ return writer;
+ }
+
+ private static String getFilenameFromType(String pOutPath,
+ String pImplName, String pExt) {
+ StringBuffer buf = new StringBuffer();
+ if ( pOutPath.isEmpty() ) {
+ buf.append( "." );
} else {
- if ( !pInterfaces.contains( "com.sun.star.lang.XServiceInfo" ) ) {
- pInterfaces.add( "com.sun.star.lang.XServiceInfo" );
- }
+ buf.append( pOutPath );
}
- if ( pPropertyHelper.equals( TypeManager.NOPROPERTYHELPER ) ) {
- pInterfaces.remove( "com.sun.star.beans.XPropertySet" );
- pInterfaces.remove( "com.sun.star.beans.XFastPropertySet" );
- pInterfaces.remove( "com.sun.star.beans.XPropertyAccess" );
+ String sep = System.getProperty( "file.separator" );
+
+ buf.append( sep );
+ buf.append( pImplName );
+ buf.append( pExt );
+
+ String filename = buf.toString();
+ // Clean up the separators
+ if ( sep.equals( "/" ) ) {
+ filename = filename.replace( "\\\\", sep );
+ } else {
+ filename = filename.replace( "/", sep );
}
+
+ return filename;
}
public static void main(String[] args) {
@@ -108,8 +121,8 @@ public class SkeletonMaker {
}
}
- private static String getLanguage( CommandLine pArgs ) {
- String[] langs = LanguageHelper.getLanguages();
+ private static Language getLanguage( CommandLine pArgs ) {
+ String[] langs = LanguageHelper.getLanguagesIds();
String lang = null;
int i = 0;
while ( lang == null && i < langs.length ) {
@@ -118,6 +131,6 @@ public class SkeletonMaker {
}
i++;
}
- return lang;
+ return LanguageHelper.getLanguage( lang );
}
}
diff --git a/src/org/openoffice/tools/TypeChecker.java b/src/org/openoffice/tools/TypeChecker.java
new file mode 100644
index 0000000..30c88af
--- /dev/null
+++ b/src/org/openoffice/tools/TypeChecker.java
@@ -0,0 +1,129 @@
+package org.openoffice.tools;
+
+import java.util.ArrayList;
+
+import org.apache.commons.cli.CommandLine;
+import org.openoffice.tools.types.TypeManager;
+
+import com.sun.star.reflection.XInterfaceAttributeTypeDescription2;
+import com.sun.star.reflection.XPropertyTypeDescription;
+
+public class TypeChecker {
+
+ private static final int MAX_INTERFACES = 12;
+
+ private TypeManager mManager;
+
+ private boolean mSupportXComp;
+ private ArrayList<String> mInterfaces;
+ private ArrayList<String> mServices;
+ private ArrayList<XPropertyTypeDescription> mProperties;
+ private ArrayList<XInterfaceAttributeTypeDescription2> mAttributes;
+ private ArrayList<String> mPropinterfaces;
+ private String mPropertyHelper;
+
+
+ public TypeChecker(TypeManager pManager) {
+ mManager = pManager;
+
+ mInterfaces = new ArrayList<String>();
+ mServices = new ArrayList<String>();
+ mProperties = new ArrayList<XPropertyTypeDescription>();
+ mAttributes = new ArrayList<XInterfaceAttributeTypeDescription2>();
+ mPropinterfaces = new ArrayList<String>();
+ mPropertyHelper = null;
+ }
+
+ public boolean isSupportXComp() {
+ return mSupportXComp;
+ }
+
+ public ArrayList<String> getInterfaces() {
+ return mInterfaces;
+ }
+
+ public ArrayList<String> getServices() {
+ return mServices;
+ }
+
+ public ArrayList<XPropertyTypeDescription> getProperties() {
+ return mProperties;
+ }
+
+ public ArrayList<XInterfaceAttributeTypeDescription2> getAttributes() {
+ return mAttributes;
+ }
+
+ public ArrayList<String> getPropinterfaces() {
+ return mPropinterfaces;
+ }
+
+ public String getPropertyHelper() {
+ return mPropertyHelper;
+ }
+
+ public void check( CommandLine pArgs ) throws DumpException {
+ // Check the types
+ String[] types = pArgs.getOptionValues( "t" );
+
+
+ // Get the service, interfaces and members from the types
+ for (String type : types) {
+ mManager.checkType( type, mServices, mInterfaces, mProperties );
+ }
+
+ // TODO For ProtocolHandler case, check the frame.ProtocolHandler and frame.XDispatch types
+
+ // Check for the property helper
+ mPropertyHelper = mManager.checkPropertyHelper( pArgs, mServices, mInterfaces, mAttributes, mPropinterfaces );
+
+ // Check the default interfaces
+ checkDefaultInterfaces( );
+
+ if ( mInterfaces.size() > MAX_INTERFACES ) {
+ throw new DumpException( "The skeletonmaker supports components with 12 interfaces only (limitation of the UNO implementation helpers)!" );
+ }
+
+ mSupportXComp = mManager.checkXComponentSupport( mInterfaces );
+ }
+
+ /**
+ * Variables usable in the template model:
+ * <ul>
+ * <li>hasLicense: boolean</li>
+ * <li>serviceObject: boolean</li>
+ * <li>supportsXComponent: boolean</li>
+ * <li>interfaces: array of interfaces properties</li>
+ * <li>propertyHelper: string (empty string or the property helper name)</li>
+ * <li>classname: string (the name of the class to create)</li>
+ * </ul>
+ *
+ * Interface objet:
+ * <ul>
+ * <li>name: string for the interface name</li>
+ * <li></li>
+ * </ul>
+ * @return
+ */
+ public Object getTemplateModel() {
+ // TODO Setup the template model using the checked infos.
+ return null;
+ }
+
+ private void checkDefaultInterfaces( ) {
+
+ if ( mServices.isEmpty() ) {
+ mInterfaces.remove( "com.sun.star.lang.XServiceInfo" );
+ } else {
+ if ( !mInterfaces.contains( "com.sun.star.lang.XServiceInfo" ) ) {
+ mInterfaces.add( "com.sun.star.lang.XServiceInfo" );
+ }
+ }
+
+ if ( mPropertyHelper.equals( TypeManager.NOPROPERTYHELPER ) ) {
+ mInterfaces.remove( "com.sun.star.beans.XPropertySet" );
+ mInterfaces.remove( "com.sun.star.beans.XFastPropertySet" );
+ mInterfaces.remove( "com.sun.star.beans.XPropertyAccess" );
+ }
+ }
+}
diff --git a/src/org/openoffice/tools/language/Language.java b/src/org/openoffice/tools/language/Language.java
new file mode 100644
index 0000000..a4e9d31
--- /dev/null
+++ b/src/org/openoffice/tools/language/Language.java
@@ -0,0 +1,106 @@
+package org.openoffice.tools.language;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.NoSuchElementException;
+import java.util.Properties;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+
+/**
+ * TODO Implement hierarchical language definitions.
+ *
+ * @author cbosdonnat
+ *
+ */
+public class Language {
+
+ private static final String PROP_DESCRIPTION = "description";
+ private static final String PROP_EXTENSION = "extension";
+
+ private static final String DESCRIPTION_FILENAME = "lang.properties";
+
+ private String mId;
+ private File mLangDir;
+
+ private Configuration mTemplateConfig;
+
+ private Properties mProps;
+
+ /**
+ * Constructor.
+ *
+ * @param pId the language identifier.
+ * @param pDir the language root directory (eg. cpp for C++).
+ *
+ * @throws IOException if the file provided isn't a proper language directory.
+ */
+ public Language( String pId, File pDir ) throws IOException {
+
+ mId = pId;
+ if ( !pDir.isDirectory() ) {
+ throw new IOException( "Invalid language directory" );
+ }
+ mLangDir = pDir;
+
+ // Define a template config for each language
+ mTemplateConfig = new Configuration();
+ mTemplateConfig.setTemplateLoader( new LanguageTemplateLoader( this ) );
+ }
+
+ public String getDescription( ) {
+ return getProperty( PROP_DESCRIPTION );
+ }
+
+ public String getExtension( ) {
+ return getProperty( PROP_EXTENSION );
+ }
+
+ public String getProperty( String pPropName ) {
+ if ( mProps == null ) {
+ loadProperties( );
+ }
+ String serialized = null;
+ Object value = mProps.get( pPropName );
+ if ( value != null ) {
+ serialized = value.toString();
+ }
+ return serialized;
+ }
+
+ public Template getTemplate( String pName ) throws IOException {
+ return mTemplateConfig.getTemplate( pName );
+ }
+
+ protected File getTemplateFile( String pName ) {
+ File result = null;
+
+ result = new File( mLangDir, pName );
+ if ( !result.isFile() || !result.canRead() ) {
+ String msg = MessageFormat.format( "No template {0} for language {1}", pName, mId );
+ throw new NoSuchElementException( msg );
+ }
+
+ return result;
+ }
+
+ private void loadProperties() {
+ mProps = new Properties();
+ File descFile = new File( mLangDir, DESCRIPTION_FILENAME );
+ if ( descFile.isFile() && descFile.canRead() ) {
+ Properties props = new Properties( );
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream( descFile );
+ props.load( in );
+ mProps.putAll( props );
+ } catch ( Exception e ) {
+ } finally {
+ try { in.close(); } catch ( Exception e) { };
+ }
+ }
+ }
+}
diff --git a/src/org/openoffice/tools/language/LanguageHelper.java b/src/org/openoffice/tools/language/LanguageHelper.java
new file mode 100644
index 0000000..b2d23b0
--- /dev/null
+++ b/src/org/openoffice/tools/language/LanguageHelper.java
@@ -0,0 +1,68 @@
+package org.openoffice.tools.language;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+/**
+ * Utility methods handling the language definitions and templates.
+ *
+ * TODO Store the language objects in a static way for perf. reasons
+ *
+ * @author cbosdonnat
+ *
+ */
+public class LanguageHelper {
+
+ private static final String DEFAULT_LANGS_DIR = "langs";
+
+ private static File sLangsDir;
+
+ /**
+ * Changes the languages configuration directory.
+ *
+ * @param pConfigDir the new directory containing the languages definitions.
+ */
+ public static void setLanguagesDir( File pConfigDir ) {
+ sLangsDir = pConfigDir;
+ }
+
+ public static String[] getLanguagesIds() {
+ File langsDir = getLangsDir();
+
+ String[] langs = langsDir.list( new FilenameFilter() {
+
+ @Override
+ public boolean accept(File pDir, String pName) {
+ return !pName.startsWith(".");
+ }
+ });
+
+ return langs;
+ }
+
+ public static Language getLanguage( String pLang ) {
+ Language language = null;
+ try {
+ language = new Language( pLang, new File( getLangsDir( ), pLang ) );
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return language;
+ }
+
+ private static File getLangsDir( ) {
+
+ if ( sLangsDir == null ) {
+ try {
+ File jarFile = new File(LanguageHelper.class.getProtectionDomain()
+ .getCodeSource().getLocation().toURI());
+ sLangsDir = new File( jarFile.getParentFile(), DEFAULT_LANGS_DIR );
+
+ } catch (URISyntaxException e) {
+ }
+ }
+ return sLangsDir;
+ }
+}
diff --git a/src/org/openoffice/tools/language/LanguageTemplateLoader.java b/src/org/openoffice/tools/language/LanguageTemplateLoader.java
new file mode 100644
index 0000000..4f6226f
--- /dev/null
+++ b/src/org/openoffice/tools/language/LanguageTemplateLoader.java
@@ -0,0 +1,33 @@
+package org.openoffice.tools.language;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.NoSuchElementException;
+
+import freemarker.cache.FileTemplateLoader;
+
+public class LanguageTemplateLoader extends FileTemplateLoader {
+
+ private Language mLang;
+
+ public LanguageTemplateLoader( Language pLangDef ) throws IOException {
+ mLang = pLangDef;
+ }
+
+ /**
+ * Delegate the template finding to the language itself.
+ *
+ * @param pName the template name to find
+ *
+ * @return the template File if found, or <code>null</code>.
+ */
+ @Override
+ public Object findTemplateSource(String pName ) throws IOException {
+ File file = null;
+ try {
+ file = mLang.getTemplateFile( pName );
+ } catch ( NoSuchElementException e ) {
+ }
+ return file;
+ }
+}
diff --git a/src/org/openoffice/tools/tests/LanguageHelperTest.java b/src/org/openoffice/tools/tests/LanguageHelperTest.java
index f6e0597..49c5b34 100644
--- a/src/org/openoffice/tools/tests/LanguageHelperTest.java
+++ b/src/org/openoffice/tools/tests/LanguageHelperTest.java
@@ -2,12 +2,21 @@ package org.openoffice.tools.tests;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import java.io.File;
+import java.io.StringWriter;
+import java.net.URISyntaxException;
import java.util.Arrays;
+import java.util.HashMap;
+import org.junit.Before;
import org.junit.Test;
-import org.openoffice.tools.LanguageHelper;
+import org.openoffice.tools.language.Language;
+import org.openoffice.tools.language.LanguageHelper;
+
+import freemarker.template.Template;
/**
* ATM, the fixture of this class is the main language configuration: it
@@ -18,30 +27,92 @@ import org.openoffice.tools.LanguageHelper;
*/
public class LanguageHelperTest {
- private static final String LANG = "cpp";
- private static final Object DESCRIPTION = "generate output for C++";
+ private static final String TESTS_LANGS_DIR = "test_langs";
+
+ private static final String WORKING_LANG = "working";
+ private static final Object WORKING_DESCRIPTION = "Working test lang";
+
+ private static final String MISSING_LANG = "missing";
+ private static final String UNCOMPLETE_LANG = "uncomplete";
- private static final String ERR_LANG = "err";
+ private static final String SIMPLE_TPL = "simple.tpl";
+ private static final String NESTED_TPL = "nested.tpl";
+
+ private static final String VAR_SOMETEXT_NAME = "sometext";
+ private static final String VAR_SOMETEXT_VALUE = "some text";
+
+ @Before
+ public void setup( ) throws URISyntaxException {
+ File jarFile = new File(LanguageHelperTest.class.getProtectionDomain()
+ .getCodeSource().getLocation().toURI());
+ File dir = new File( jarFile.getParentFile(), TESTS_LANGS_DIR );
+ LanguageHelper.setLanguagesDir( dir );
+ }
@Test
public void testGetLanguages( ) {
- String[] result = LanguageHelper.getLanguages();
- String[] expected = new String[] { "cpp", "java4", "java5" };
+ String[] result = LanguageHelper.getLanguagesIds();
+ String[] expected = new String[] { WORKING_LANG, UNCOMPLETE_LANG };
// The order in results aren't guaranteed
Arrays.sort( result );
+ Arrays.sort( expected );
assertArrayEquals( "Different values", expected, result );
}
@Test
public void testGetDescriptionOk( ) {
- String actual = LanguageHelper.getDescription( LANG );
- assertEquals( DESCRIPTION , actual );
+ Language langDef = LanguageHelper.getLanguage( WORKING_LANG );
+ assertNotNull( langDef );
+ String actual = langDef.getDescription( );
+ assertEquals( WORKING_DESCRIPTION , actual );
}
@Test
- public void testGetDescriptionError( ) {
- String actual = LanguageHelper.getDescription( ERR_LANG );
+ public void testGetLanguageMissing( ) {
+ Language langDef = LanguageHelper.getLanguage( MISSING_LANG );
+ assertNull( langDef );
+ }
+
+ @Test
+ public void testGetLanguageMissingProp( ) {
+ Language langDef = LanguageHelper.getLanguage( UNCOMPLETE_LANG );
+ assertNotNull( langDef );
+ String actual = langDef.getDescription();
assertNull( actual );
}
+
+ @Test
+ public void testSimpleTemplate( ) throws Exception {
+ Language langDef = LanguageHelper.getLanguage( WORKING_LANG );
+ assertNotNull( langDef );
+
+ Template tpl = langDef.getTemplate( SIMPLE_TPL );
+ StringWriter out = new StringWriter();
+ tpl.process( getTestTemplateModel(), out );
+ out.flush();
+
+ String expected = VAR_SOMETEXT_VALUE;
+ assertEquals( expected, out.toString() );
+ }
+
+ @Test
+ public void testNestedTemplate( ) throws Exception {
+ Language langDef = LanguageHelper.getLanguage( WORKING_LANG );
+ assertNotNull( langDef );
+
+ Template tpl = langDef.getTemplate( NESTED_TPL );
+ StringWriter out = new StringWriter();
+ tpl.process( getTestTemplateModel(), out );
+ out.flush();
+
+ String expected = VAR_SOMETEXT_VALUE + "\n" + VAR_SOMETEXT_VALUE;
+ assertEquals( expected, out.toString() );
+ }
+
+ private Object getTestTemplateModel() {
+ HashMap<String, Object> model = new HashMap<String, Object>();
+ model.put( VAR_SOMETEXT_NAME, VAR_SOMETEXT_VALUE );
+ return model;
+ }
}
diff --git a/src/org/openoffice/tools/types/TypeManager.java b/src/org/openoffice/tools/types/TypeManager.java
index b105a4f..c8b9085 100644
--- a/src/org/openoffice/tools/types/TypeManager.java
+++ b/src/org/openoffice/tools/types/TypeManager.java
@@ -147,6 +147,7 @@ public class TypeManager {
}
boolean oldStyleWithProps = false;
+ boolean propMixin = Boolean.parseBoolean( pArgs.getOptionValue( "propertysetmixin" ) );
while ( it.hasNext() && result.isEmpty() ) {
String typename = it.next( );
try {
@@ -154,7 +155,6 @@ public class TypeManager {
if ( !pServices.isEmpty() ) {
Service service = new Service( typeDesc );
- boolean propMixin = Boolean.parseBoolean( pArgs.getOptionValue( "propertysetmixin" ) );
if ( propMixin && service.getSupertype() != null ) {
Interface iface = new Interface( service.getSupertype() );
iface.checkAttributes( pAttributes, pPropinterfaces );
diff --git a/test_langs/uncomplete/lang.properties b/test_langs/uncomplete/lang.properties
new file mode 100644
index 0000000..d8be2b8
--- /dev/null
+++ b/test_langs/uncomplete/lang.properties
@@ -0,0 +1,2 @@
+#description isn't provided to test failures here
+extension = unc \ No newline at end of file
diff --git a/test_langs/working/lang.properties b/test_langs/working/lang.properties
new file mode 100644
index 0000000..9790447
--- /dev/null
+++ b/test_langs/working/lang.properties
@@ -0,0 +1,2 @@
+description = Working test lang
+extension = tst \ No newline at end of file
diff --git a/test_langs/working/nested.tpl b/test_langs/working/nested.tpl
new file mode 100644
index 0000000..9618299
--- /dev/null
+++ b/test_langs/working/nested.tpl
@@ -0,0 +1,2 @@
+${sometext}
+<#include "simple.tpl"/> \ No newline at end of file
diff --git a/test_langs/working/simple.tpl b/test_langs/working/simple.tpl
new file mode 100644
index 0000000..bdfdaaa
--- /dev/null
+++ b/test_langs/working/simple.tpl
@@ -0,0 +1 @@
+${sometext} \ No newline at end of file