diff --git a/.classpath b/.classpath
index d4238a1..6980c66 100644
--- a/.classpath
+++ b/.classpath
@@ -22,5 +22,6 @@
+
diff --git a/lib/README b/lib/README
index 1e2e5da..479e0b5 100644
--- a/lib/README
+++ b/lib/README
@@ -1,5 +1,6 @@
Description of used libraries:
- activation: STU
+- devinsy-utils : useful tools (StringList...)
- hamcrest-core: required by junit
- junit: unit tests API
- log4j: log API
diff --git a/lib/devinsy-utils-0.2.4-sources.zip b/lib/devinsy-utils-0.2.4-sources.zip
new file mode 100644
index 0000000..ac88eb7
Binary files /dev/null and b/lib/devinsy-utils-0.2.4-sources.zip differ
diff --git a/lib/devinsy-utils-0.2.4.jar b/lib/devinsy-utils-0.2.4.jar
new file mode 100644
index 0000000..802aefa
Binary files /dev/null and b/lib/devinsy-utils-0.2.4.jar differ
diff --git a/src/fr/devinsy/xidyn/presenters/DomPresenter.java b/src/fr/devinsy/xidyn/presenters/DomPresenter.java
index e315d2f..85e4ea1 100644
--- a/src/fr/devinsy/xidyn/presenters/DomPresenter.java
+++ b/src/fr/devinsy/xidyn/presenters/DomPresenter.java
@@ -116,6 +116,27 @@ public class DomPresenter implements Presenter
return (result);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isAvailable()
+ {
+ boolean result;
+
+ if (this.dom == null)
+ {
+ result = false;
+ }
+ else
+ {
+ result = true;
+ }
+
+ //
+ return result;
+ }
+
/**
* {@inheritDoc}
*/
@@ -153,6 +174,7 @@ public class DomPresenter implements Presenter
*
* @throws Exception
*/
+ @Override
public void update() throws Exception
{
diff --git a/src/fr/devinsy/xidyn/presenters/FilePresenter.java b/src/fr/devinsy/xidyn/presenters/FilePresenter.java
index be6e421..93136ee 100644
--- a/src/fr/devinsy/xidyn/presenters/FilePresenter.java
+++ b/src/fr/devinsy/xidyn/presenters/FilePresenter.java
@@ -112,6 +112,27 @@ public class FilePresenter extends StringPresenter
return (result);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isAvailable()
+ {
+ boolean result;
+
+ if ((this.source == null) || (!this.source.exists()))
+ {
+ result = false;
+ }
+ else
+ {
+ result = true;
+ }
+
+ //
+ return result;
+ }
+
/**
* {@inheritDoc}
*/
@@ -197,6 +218,7 @@ public class FilePresenter extends StringPresenter
/**
* @throws Exception
*/
+ @Override
public void update() throws Exception
{
//
diff --git a/src/fr/devinsy/xidyn/presenters/GenericPresenter.java b/src/fr/devinsy/xidyn/presenters/GenericPresenter.java
new file mode 100644
index 0000000..1d65b8a
--- /dev/null
+++ b/src/fr/devinsy/xidyn/presenters/GenericPresenter.java
@@ -0,0 +1,203 @@
+package fr.devinsy.xidyn.presenters;
+
+import java.io.File;
+import java.net.URL;
+
+import fr.devinsy.xidyn.data.TagDataManager;
+
+/**
+ *
+ */
+public class GenericPresenter implements Presenter
+{
+ private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(GenericPresenter.class);
+ private Presenter presenter;
+
+ /**
+ *
+ */
+ public GenericPresenter(final File source)
+ {
+ if (source == null)
+ {
+ throw new NullPointerException("source is null");
+ }
+ else
+ {
+ this.presenter = PresenterFactory.get(source);
+ }
+ }
+
+ /**
+ *
+ */
+ public GenericPresenter(final String source)
+ {
+ if (source == null)
+ {
+ throw new NullPointerException("source is null");
+ }
+ else
+ {
+ this.presenter = PresenterFactory.get(source);
+ }
+ }
+
+ /**
+ *
+ */
+ public GenericPresenter(final URL source)
+ {
+ if (source == null)
+ {
+ throw new NullPointerException("source is null");
+ }
+ else
+ {
+ this.presenter = PresenterFactory.get(source);
+ }
+ }
+
+ /**
+ *
+ */
+ @Override
+ public StringBuffer dynamize() throws Exception
+ {
+ StringBuffer result;
+
+ result = this.presenter.dynamize();
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public StringBuffer dynamize(final TagDataManager datas) throws Exception
+ {
+ StringBuffer result;
+
+ result = this.presenter.dynamize(datas);
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public Object getSource()
+ {
+ Object result;
+
+ result = this.presenter.getSource();
+
+ //
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isAvailable()
+ {
+ boolean result;
+
+ result = this.presenter.isAvailable();
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public boolean isOutdated() throws Exception
+ {
+ boolean result;
+
+ result = this.presenter.isOutdated();
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ * @param source
+ */
+ public void setSource(final File source)
+ {
+ if (source == null)
+ {
+ throw new NullPointerException("source is null");
+ }
+ else
+ {
+ this.presenter = PresenterFactory.get(source);
+ }
+ }
+
+ /**
+ *
+ * @param source
+ */
+ public void setSource(final String source)
+ {
+ if (source == null)
+ {
+ throw new NullPointerException("source is null");
+ }
+ else
+ {
+ this.presenter = PresenterFactory.get(source);
+ }
+ }
+
+ /**
+ *
+ * @param source
+ */
+ public void setSource(final URL source)
+ {
+ if (source == null)
+ {
+ throw new NullPointerException("source is null");
+ }
+ else
+ {
+ this.presenter = PresenterFactory.get(source);
+ }
+ }
+
+ /**
+ *
+ */
+ public String toString(final String language) throws Exception
+ {
+ String result;
+
+ result = this.presenter.toString();
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public void update() throws Exception
+ {
+ this.presenter.update();
+
+ }
+}
+
+// ////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/src/fr/devinsy/xidyn/presenters/Presenter.java b/src/fr/devinsy/xidyn/presenters/Presenter.java
index 109a514..7306ab1 100644
--- a/src/fr/devinsy/xidyn/presenters/Presenter.java
+++ b/src/fr/devinsy/xidyn/presenters/Presenter.java
@@ -10,7 +10,8 @@ import fr.devinsy.xidyn.data.TagDataManager;
*
be aware to avoid copy action (performance)
*
*/
-public interface Presenter {
+public interface Presenter
+{
/**
*
@@ -34,9 +35,21 @@ public interface Presenter {
*/
public Object getSource();
+ /**
+ * This method check if the source exists and it is readable.
+ *
+ * @return
+ */
+ public boolean isAvailable();
+
/**
*
* @return
*/
public boolean isOutdated() throws Exception;
+
+ /**
+ *
+ */
+ public void update() throws Exception;
}
diff --git a/src/fr/devinsy/xidyn/presenters/PresenterFactory.java b/src/fr/devinsy/xidyn/presenters/PresenterFactory.java
new file mode 100644
index 0000000..0aa2ffc
--- /dev/null
+++ b/src/fr/devinsy/xidyn/presenters/PresenterFactory.java
@@ -0,0 +1,100 @@
+package fr.devinsy.xidyn.presenters;
+
+import java.io.File;
+import java.net.URL;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class PresenterFactory
+{
+ static private Logger logger = LoggerFactory.getLogger(PresenterFactory.class);
+
+ /**
+ *
+ * @param source
+ * @return
+ */
+ public static Presenter get(final File source)
+ {
+ Presenter result;
+
+ if (source == null)
+ {
+ result = null;
+ }
+ else
+ {
+ result = new FilePresenter(source);
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ * @param source
+ * @return
+ */
+ public static Presenter get(final String source)
+ {
+ Presenter result;
+
+ if (source == null)
+ {
+ result = null;
+ }
+ else if (source.startsWith("file://"))
+ {
+ result = new FilePresenter(source);
+ }
+ else if (source.matches(".+://.+"))
+ {
+ result = new URLPresenter(source);
+ }
+ else if (source.startsWith("/"))
+ {
+ if (new File(source).exists())
+ {
+ result = new FilePresenter(source);
+ }
+ else
+ {
+ result = new URLPresenter(source);
+ }
+ }
+ else
+ {
+ result = new StringPresenter(source);
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ * @param source
+ * @return
+ */
+ public static Presenter get(final URL source)
+ {
+ Presenter result;
+
+ if (source == null)
+ {
+ result = null;
+ }
+ else
+ {
+ result = new URLPresenter(source);
+ }
+
+ //
+ return result;
+ }
+}
diff --git a/src/fr/devinsy/xidyn/presenters/StringPresenter.java b/src/fr/devinsy/xidyn/presenters/StringPresenter.java
index 8b744ea..2497455 100644
--- a/src/fr/devinsy/xidyn/presenters/StringPresenter.java
+++ b/src/fr/devinsy/xidyn/presenters/StringPresenter.java
@@ -154,6 +154,27 @@ public class StringPresenter implements Presenter
return (result);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isAvailable()
+ {
+ boolean result;
+
+ if (this.source == null)
+ {
+ result = false;
+ }
+ else
+ {
+ result = true;
+ }
+
+ //
+ return result;
+ }
+
/**
* {@inheritDoc}
*/
@@ -185,6 +206,15 @@ public class StringPresenter implements Presenter
this.dom = null;
}
+ /**
+ *
+ */
+ @Override
+ public void update() throws Exception
+ {
+ // Nothing to do.
+ }
+
/**
* Dynamize a string with HTML in.
*/
diff --git a/src/fr/devinsy/xidyn/presenters/TranslatorPresenter.java b/src/fr/devinsy/xidyn/presenters/TranslatorPresenter.java
new file mode 100644
index 0000000..725cfb1
--- /dev/null
+++ b/src/fr/devinsy/xidyn/presenters/TranslatorPresenter.java
@@ -0,0 +1,194 @@
+package fr.devinsy.xidyn.presenters;
+
+import java.util.HashMap;
+
+import fr.devinsy.util.FileTools;
+import fr.devinsy.xidyn.data.TagDataManager;
+
+/**
+ *
+ */
+public class TranslatorPresenter implements Presenter
+{
+ private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TranslatorPresenter.class);
+ private String defaultSource;
+ private HashMap presenters;
+
+ /**
+ *
+ */
+ public TranslatorPresenter(final String defaultSource)
+ {
+
+ if (defaultSource == null)
+ {
+ throw new NullPointerException("defaultSource is null");
+ }
+ else
+ {
+ this.defaultSource = defaultSource;
+ this.presenters = new HashMap();
+ }
+ }
+
+ /**
+ *
+ */
+ @Override
+ public StringBuffer dynamize() throws Exception
+ {
+ StringBuffer result;
+
+ Presenter presenter = getPresenter(null);
+ if (presenter == null)
+ {
+ result = null;
+ }
+ else
+ {
+ result = presenter.dynamize();
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public StringBuffer dynamize(final TagDataManager datas) throws Exception
+ {
+ StringBuffer result;
+
+ Presenter presenter = getPresenter(null);
+ if (presenter == null)
+ {
+ result = null;
+ }
+ else
+ {
+ result = presenter.dynamize(datas);
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ public Presenter getPresenter(final String language) throws Exception
+ {
+ Presenter result;
+
+ //
+ result = this.presenters.get(language);
+
+ //
+ if (result == null)
+ {
+ //
+ if (language == null)
+ {
+ //
+ result = PresenterFactory.get(this.defaultSource);
+
+ if (result.isAvailable())
+ {
+ this.presenters.put(language, result);
+ }
+ else
+ {
+ throw new Exception("Undefined default language file.");
+ }
+ }
+ else
+ {
+ String adaptedSource = FileTools.addBeforeExtension(defaultSource, "-" + language);
+ result = PresenterFactory.get(adaptedSource);
+
+ if (result.isAvailable())
+ {
+ this.presenters.put(language, result);
+ }
+ else
+ {
+ result = getPresenter(null);
+ }
+ }
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public Object getSource()
+ {
+ String result;
+
+ result = this.defaultSource;
+
+ //
+ return result;
+ }
+
+ @Override
+ public boolean isAvailable()
+ {
+ boolean result;
+
+ try
+ {
+ result = getPresenter(null).isAvailable();
+ }
+ catch (Exception exception)
+ {
+ result = false;
+ }
+
+ //
+ return result;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public boolean isOutdated() throws Exception
+ {
+ return false;
+ }
+
+ /**
+ *
+ */
+ public String toString(final String language) throws Exception
+ {
+ String result;
+
+ Presenter presenter = getPresenter(language);
+ if (presenter == null)
+ {
+ result = null;
+ }
+ else
+ {
+ result = presenter.toString();
+ }
+
+ //
+ return result;
+ }
+
+ @Override
+ public void update() throws Exception
+ {
+ }
+}
+
+// ////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/src/fr/devinsy/xidyn/presenters/URLPresenter.java b/src/fr/devinsy/xidyn/presenters/URLPresenter.java
index 105ff7d..db76b31 100644
--- a/src/fr/devinsy/xidyn/presenters/URLPresenter.java
+++ b/src/fr/devinsy/xidyn/presenters/URLPresenter.java
@@ -94,14 +94,7 @@ public class URLPresenter extends StringPresenter
{
String result;
- if (this.source == null)
- {
- result = null;
- }
- else
- {
- result = this.source.toString();
- }
+ result = this.sourcePathname;
//
return (result);
@@ -120,6 +113,55 @@ public class URLPresenter extends StringPresenter
return (result);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isAvailable()
+ {
+ boolean result;
+
+ if (this.source == null)
+ {
+ result = false;
+ }
+ else if (sourcePathname.startsWith("/"))
+ {
+ /*
+ * In case of Jar resources, if resource does not exist then
+ * this.source is null. So, if we are here in the code then
+ * this.source is not null and so resource is available.
+ */
+ result = true;
+ }
+ else
+ {
+ /*
+ * The source is an URL with protocol. Open a stream is the only way to test if the resource is available.
+ */
+ try
+ {
+ this.source.openStream();
+ result = true;
+ }
+ catch (final IOException exception)
+ {
+ /*
+ * On URL.openStream:
+ *
+ * - If host does not exist then a java.net.UnknownHostException is throwed.
+ * - If host exists but not the file does not exist then a java.io.FileNotFoundException is throwed.
+ *
+ * These exceptions are IOException.
+ */
+ result = false;
+ }
+ }
+
+ //
+ return result;
+ }
+
/**
* {@inheritDoc}
*
@@ -220,7 +262,7 @@ public class URLPresenter extends StringPresenter
//
result = super.getSource();
}
- catch (final IOException exception)
+ catch (final Exception exception)
{
result = null;
}
@@ -232,9 +274,10 @@ public class URLPresenter extends StringPresenter
/**
* No need to be synchronized.
*
- * @throws IOException
+ * @throws Exception
*/
- public void update() throws IOException
+ @Override
+ public void update() throws Exception
{
//
if (this.source == null)
@@ -245,11 +288,27 @@ public class URLPresenter extends StringPresenter
}
else
{
- long currentSourceTime = this.source.openConnection().getLastModified();
- if ((super.getSource() == null) || (this.sourceTime != currentSourceTime))
+ try
{
- super.setSource(XidynUtils.load(this.source));
- this.sourceTime = currentSourceTime;
+ long currentSourceTime = this.source.openConnection().getLastModified();
+ if ((super.getSource() == null) || (this.sourceTime != currentSourceTime))
+ {
+ super.setSource(XidynUtils.load(this.source));
+ this.sourceTime = currentSourceTime;
+ }
+ }
+ catch (final IOException exception)
+ {
+ /* On URL.openStream:
+ *
+ * - If host does not exist then a java.net.UnknownHostException is throwed.
+ * - If host exists but not the file does not exist then a java.io.FileNotFoundException is throwed.
+ *
+ * These exceptions are IOException.
+ */
+ String errorMessage = "source file defined but not readable (" + this.source.toString() + ")";
+ logger.error(errorMessage);
+ throw new Exception(errorMessage);
}
}
}