diff --git a/migration/i1.0a-release/oracle/201303281606_IDEMPIERE-810.sql b/migration/i1.0a-release/oracle/201303281606_IDEMPIERE-810.sql
new file mode 100644
index 0000000000..bd0ce95122
--- /dev/null
+++ b/migration/i1.0a-release/oracle/201303281606_IDEMPIERE-810.sql
@@ -0,0 +1,12 @@
+-- Mar 19, 2013 2:48:21 PM COT
+-- IDEMPIERE-810 Allow Translation Import from webui
+INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Import ZIP',200156,'D','2f5186f7-44bf-4e1f-a7b7-a4061809eeae','ImportZIP','Y',TO_DATE('2013-03-19 14:48:20','YYYY-MM-DD HH24:MI:SS'),0,0,0,0,TO_DATE('2013-03-19 14:48:20','YYYY-MM-DD HH24:MI:SS'))
+;
+
+-- Mar 19, 2013 2:48:21 PM COT
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200156 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+
+SELECT register_migration_script('201303281606_IDEMPIERE-810.sql') FROM dual
+;
+
diff --git a/migration/i1.0a-release/postgresql/201303281606_IDEMPIERE-810.sql b/migration/i1.0a-release/postgresql/201303281606_IDEMPIERE-810.sql
new file mode 100644
index 0000000000..44153ce72e
--- /dev/null
+++ b/migration/i1.0a-release/postgresql/201303281606_IDEMPIERE-810.sql
@@ -0,0 +1,13 @@
+-- Mar 19, 2013 2:48:21 PM COT
+-- Mar 19, 2013 2:48:21 PM COT
+INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,EntityType,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,AD_Client_ID,AD_Org_ID,Created) VALUES ('I','Import ZIP',200156,'D','2f5186f7-44bf-4e1f-a7b7-a4061809eeae','ImportZIP','Y',TO_TIMESTAMP('2013-03-19 14:48:20','YYYY-MM-DD HH24:MI:SS'),0,0,0,0,TO_TIMESTAMP('2013-03-19 14:48:20','YYYY-MM-DD HH24:MI:SS'))
+;
+
+-- Mar 19, 2013 2:48:21 PM COT
+-- I forgot to set the DICTIONARY_ID_COMMENTS System Configurator
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy,AD_Message_Trl_UU ) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy,Generate_UUID() FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=200156 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+
+SELECT register_migration_script('201303281606_IDEMPIERE-810.sql') FROM dual
+;
+
diff --git a/org.adempiere.server-feature/server.product.launch b/org.adempiere.server-feature/server.product.launch
index 62ef88a07d..07a3f843fe 100644
--- a/org.adempiere.server-feature/server.product.launch
+++ b/org.adempiere.server-feature/server.product.launch
@@ -21,7 +21,7 @@
-
+
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java
index 9dc856036d..66d2014edc 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java
@@ -14,6 +14,7 @@
package org.adempiere.webui.component;
import java.io.File;
+import java.util.Arrays;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.theme.ThemeManager;
@@ -132,6 +133,7 @@ public class FolderBrowser extends Window implements EventListener
}
File[] files = dir.listFiles();
+ Arrays.sort(files);
for(File file: files)
{
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/install/WTranslationDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/install/WTranslationDialog.java
index 0587abd727..02d314063e 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/install/WTranslationDialog.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/install/WTranslationDialog.java
@@ -13,9 +13,19 @@
*****************************************************************************/
package org.adempiere.webui.install;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.logging.Level;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.adempiere.exceptions.AdempiereException;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.FolderBrowser;
@@ -33,15 +43,20 @@ import org.adempiere.webui.panel.CustomForm;
import org.adempiere.webui.panel.IFormController;
import org.adempiere.webui.panel.StatusBarPanel;
import org.adempiere.webui.session.SessionManager;
+import org.adempiere.webui.util.ReaderInputStream;
import org.adempiere.webui.window.FDialog;
+import org.apache.commons.io.FileUtils;
import org.compiere.install.Translation;
import org.compiere.install.TranslationController;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.ValueNamePair;
+import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
+import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Div;
@@ -84,6 +99,7 @@ public class WTranslationDialog extends TranslationController implements IFormCo
private Button bExport = new Button();
private Button bImport = new Button();
+ private Button bImportZIP = new Button();
private Label lClient = new Label();
private Listbox cbClient = ListboxFactory.newDropdownListbox();
@@ -108,9 +124,13 @@ public class WTranslationDialog extends TranslationController implements IFormCo
//
bExport.setLabel(Msg.getMsg(Env.getCtx(), "Export"));
bExport.addActionListener(this);
+ bExport.setStyle("text-align: right;");
bImport.setLabel(Msg.getMsg(Env.getCtx(), "Import"));
bImport.addActionListener(this);
-
+ bImportZIP.setLabel(Msg.getMsg(Env.getCtx(), "ImportZIP"));
+ bImportZIP.setUpload("true");
+ bImportZIP.addEventListener(Events.ON_UPLOAD, this);
+
Rows rows = centerLayout.newRows();
Row row = rows.newRow();
row.appendChild(lClient.rightAlign());
@@ -124,13 +144,21 @@ public class WTranslationDialog extends TranslationController implements IFormCo
row.appendChild(lTable.rightAlign());
row.appendChild(cbTable);
+ row = rows.newRow();
Div div = new Div();
div.setStyle("text-align: right;");
div.appendChild(bExport);
-
- row = rows.newRow();
row.appendChild(div);
- row.appendChild(bImport);
+
+ div = new Div();
+ div.setStyle("text-align: center;");
+ div.appendChild(bImport);
+ row.appendChild(div);
+
+ div = new Div();
+ div.setStyle("text-align: left;");
+ div.appendChild(bImportZIP);
+ row.appendChild(div);
}
/**
@@ -166,6 +194,10 @@ public class WTranslationDialog extends TranslationController implements IFormCo
SessionManager.getAppDesktop().closeActiveWindow();
} // dispose
+ public ADForm getForm() {
+ return form;
+ }
+
/**************************************************************************
* Action Listener
* @param e event
@@ -192,7 +224,7 @@ public class WTranslationDialog extends TranslationController implements IFormCo
if (m_AD_Table == null)
return;
- m_imp = (e.getTarget() == bImport);
+ m_imp = (e.getTarget() == bImport || e.getTarget() == bImportZIP);
m_AD_Client_ID = -1;
KeyNamePair AD_Client = null;
@@ -201,65 +233,178 @@ public class WTranslationDialog extends TranslationController implements IFormCo
if (AD_Client != null)
m_AD_Client_ID = AD_Client.getKey();
-
+
+ if (e instanceof UploadEvent)
+ {
+ // upload and import zip
+ UploadEvent ue = (UploadEvent) e;
+ try {
+ processUploadMedia(ue.getMedia());
+ } catch (AdempiereException e1) {
+ throw new RuntimeException(e1);
+ }
+ return;
+ }
+
final FolderBrowser directoryDialog = new FolderBrowser(true);
directoryDialog.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
callImportProcess(directoryDialog.getPath());
}
-
- private void callImportProcess(String path) {
- String directory = directoryDialog.getPath();
-
- if(directory == null) return;
- //
- statusBar.setStatusLine(directory);
-
- Translation t = new Translation(Env.getCtx());
- StringBuilder msg = new StringBuilder(t.validateLanguage(m_AD_Language.getValue()));
- if (msg.length() > 0)
- {
- FDialog.error(m_WindowNo, form, "LanguageSetupError", msg.toString());
- return;
- }
-
- // All Tables
- if (m_AD_Table.getValue().equals(""))
- {
- msg = new StringBuilder();
-
- for (int i = 1; i < cbTable.getItemCount(); i++)
- {
- m_AD_Table = (ValueNamePair)cbTable.getItemAtIndex(i).toValueNamePair();
- // Carlos Ruiz - globalqss - improve output message from translation import process
- msg.append(m_AD_Table.getValue()).append(" ").append((m_imp
- ? t.importTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue())
- : t.exportTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue()))).append(" ");
- }
-
- if(msg == null || msg.length() == 0)
- msg = new StringBuilder((m_imp ? "Import" : "Export")).append(" Successful. [").append(directory).append("]");
-
- statusBar.setStatusLine(msg.toString());
- }
- else // single table
- {
- msg = null;
- msg = new StringBuilder(m_imp
- ? t.importTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue())
- : t.exportTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue()));
-
- if(msg == null || msg.length() == 0)
- msg = new StringBuilder(m_imp ? "Import" : "Export").append(" Successful. [").append(directory).append("]");
-
- statusBar.setStatusLine(msg.toString());
- }
- }
});
- } // actionPerformed
-
- public ADForm getForm() {
- return form;
+ } // onEvent
+
+ private void callImportProcess(String directory) {
+ if(directory == null) return;
+ //
+ statusBar.setStatusLine(directory);
+
+ Translation t = new Translation(Env.getCtx());
+ StringBuilder msg = new StringBuilder(t.validateLanguage(m_AD_Language.getValue()));
+ if (msg.length() > 0)
+ {
+ FDialog.error(m_WindowNo, form, "LanguageSetupError", msg.toString());
+ return;
+ }
+
+ // All Tables
+ if (m_AD_Table.getValue().equals(""))
+ {
+ msg = new StringBuilder();
+
+ for (int i = 1; i < cbTable.getItemCount(); i++)
+ {
+ m_AD_Table = (ValueNamePair)cbTable.getItemAtIndex(i).toValueNamePair();
+ // Carlos Ruiz - globalqss - improve output message from translation import process
+ msg.append(m_AD_Table.getValue()).append(" ").append((m_imp
+ ? t.importTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue())
+ : t.exportTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue()))).append(" ");
+ }
+
+ if(msg == null || msg.length() == 0)
+ msg = new StringBuilder((m_imp ? "Import" : "Export")).append(" Successful. [").append(directory).append("]");
+
+ statusBar.setStatusLine(msg.toString());
+ }
+ else // single table
+ {
+ msg = null;
+ msg = new StringBuilder(m_imp
+ ? t.importTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue())
+ : t.exportTrl (directory, m_AD_Client_ID, m_AD_Language.getValue(), m_AD_Table.getValue()));
+
+ if(msg == null || msg.length() == 0)
+ msg = new StringBuilder(m_imp ? "Import" : "Export").append(" Successful. [").append(directory).append("]");
+
+ statusBar.setStatusLine(msg.toString());
+ }
}
+
+ private void processUploadMedia(Media media) throws AdempiereException {
+ if (media == null)
+ return;
+
+ InputStream istream;
+ if (media.isBinary()) {
+ istream = media.getStreamData();
+ } else {
+ istream = new ReaderInputStream(media.getReaderData());
+ }
+
+ if (log.isLoggable(Level.CONFIG)) log.config(media.getName());
+
+ unZipAndProcess(istream);
+ }
+
+ private void unZipAndProcess(InputStream istream) throws AdempiereException {
+ FileOutputStream ostream = null;
+ File file = null;
+ try {
+ file = File.createTempFile("trlImport", ".zip");
+ ostream = new FileOutputStream(file);
+ byte[] buffer = new byte[1024];
+ int read;
+ while ((read = istream.read(buffer)) != -1) {
+ ostream.write(buffer, 0, read);
+ }
+ } catch (Throwable e) {
+ throw new AdempiereException("Copy zip failed", e);
+ } finally {
+ if (ostream != null) {
+ try {
+ ostream.close();
+ } catch (Exception e2) {}
+ }
+ }
+
+ // create temp folder
+ File tempfolder;
+ try {
+ tempfolder = File.createTempFile(m_AD_Language.getValue(), ".trl");
+ tempfolder.delete();
+ tempfolder.mkdir();
+ } catch (IOException e1) {
+ throw new AdempiereException("Problem creating temp folder", e1);
+ }
+
+ String suffix = "_" + m_AD_Language.getValue() + ".xml";
+ ZipFile zipFile = null;
+ boolean validfile = false;
+ try {
+ zipFile = new ZipFile(file);
+
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = (ZipEntry)entries.nextElement();
+
+ if (entry.isDirectory()) {
+ // ignore folders
+ log.warning("Imported zip must not contain folders, ignored folder" + entry.getName());
+ continue;
+ }
+
+ if (! entry.getName().endsWith(suffix)) {
+ // not valid file
+ log.warning("Ignored file " + entry.getName());
+ continue;
+ }
+
+ if (log.isLoggable(Level.INFO)) log.info("Extracting file: " + entry.getName());
+ copyInputStream(zipFile.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(tempfolder.getPath() + File.separator + entry.getName())));
+ validfile = true;
+ }
+ } catch (Throwable e) {
+ throw new AdempiereException("Uncompress zip failed", e);
+ } finally {
+ if (zipFile != null)
+ try {
+ zipFile.close();
+ } catch (IOException e) {}
+ }
+
+ if (!validfile) {
+ throw new AdempiereException("ZIP file invalid, doesn't contain *" + suffix + " files");
+ }
+
+ callImportProcess(tempfolder.getPath());
+
+ file.delete();
+ try {
+ FileUtils.deleteDirectory(tempfolder);
+ } catch (IOException e) {}
+ }
+
+ public static final void copyInputStream(InputStream in, OutputStream out) throws IOException
+ {
+ byte[] buffer = new byte[1024];
+ int len;
+
+ while((len = in.read(buffer)) >= 0)
+ out.write(buffer, 0, len);
+
+ in.close();
+ out.close();
+ }
+
}