Merge release-7.1 into master
This commit is contained in:
commit
a2ade6340a
|
@ -0,0 +1,43 @@
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:03:49 PM MYT
|
||||||
|
-- 1006528 Implement Image Storage Provider
|
||||||
|
INSERT INTO AD_Element (AD_Element_ID,ColumnName,Updated,Name,Description,PrintName,AD_Element_UU,IsActive,Created,AD_Org_ID,CreatedBy,UpdatedBy,AD_Client_ID,EntityType) VALUES (203038,'StorageImage_ID',TO_DATE('2016-08-18 21:03:42','YYYY-MM-DD HH24:MI:SS'),'Image Store','Storage provider for Image','Image Store','a4df3881-4d7e-4b3b-a71a-3380bdebf371','Y',TO_DATE('2016-08-18 21:03:42','YYYY-MM-DD HH24:MI:SS'),0,100,100,0,'D')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:05:23 PM MYT
|
||||||
|
INSERT INTO AD_Column (AD_Column_ID,SeqNoSelection,IsSyncDatabase,Version,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,Updated,IsUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,AD_Org_ID,Created,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID) VALUES (212831,0,'N',0,'N','N','N',0,'N',22,'N','N','N','Y','a3d7a4ea-9d2e-4da6-b48f-7ee5242719ee',TO_DATE('2016-08-18 21:05:07','YYYY-MM-DD HH24:MI:SS'),'Y','StorageImage_ID','Storage provider for Image','Image Store','Y','Y',100,100,'N','N',0,0,TO_DATE('2016-08-18 21:05:07','YYYY-MM-DD HH24:MI:SS'),'D','N','N','N',203038,18,200023,227)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:05:59 PM MYT
|
||||||
|
UPDATE AD_Column SET FKConstraintType='N', FKConstraintName='StorageImage_ADClientInfo',Updated=TO_DATE('2016-08-18 21:05:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212831
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:05:59 PM MYT
|
||||||
|
ALTER TABLE AD_ClientInfo ADD StorageImage_ID NUMBER(10) DEFAULT NULL
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:06:00 PM MYT
|
||||||
|
ALTER TABLE AD_ClientInfo ADD CONSTRAINT StorageImage_ADClientInfo FOREIGN KEY (StorageImage_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:07:51 PM MYT
|
||||||
|
INSERT INTO AD_Field (SortNo,AD_Field_ID,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,IsReadOnly,AD_Org_ID,Updated,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,CreatedBy,UpdatedBy,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,Created,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,AD_Tab_ID) VALUES (0,204272,'N',0,'N','N',1020,'Y','N',0,TO_DATE('2016-08-18 21:07:45','YYYY-MM-DD HH24:MI:SS'),'Storage provider for Image','Image Store','471cc623-0460-4b6a-8e24-74055858ce8a','Y','N',100,100,'Y','Y',1020,1,'N',0,TO_DATE('2016-08-18 21:07:45','YYYY-MM-DD HH24:MI:SS'),2,1,'N','N',212831,'D',169)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:08:51 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=120, IsDisplayed='Y', XPosition=1,Updated=TO_DATE('2016-08-18 21:08:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204272
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:08:51 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=125,Updated=TO_DATE('2016-08-18 21:08:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202532
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:08:51 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=130,Updated=TO_DATE('2016-08-18 21:08:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202533
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('201608191500_Ticket_1006528.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
-- Aug 18, 2016 9:03:49 PM MYT
|
||||||
|
-- 1006528 Implement Image Storage Provider
|
||||||
|
INSERT INTO AD_Element (AD_Element_ID,ColumnName,Updated,Name,Description,PrintName,AD_Element_UU,IsActive,Created,AD_Org_ID,CreatedBy,UpdatedBy,AD_Client_ID,EntityType) VALUES (203038,'StorageImage_ID',TO_TIMESTAMP('2016-08-18 21:03:42','YYYY-MM-DD HH24:MI:SS'),'Image Store','Storage provider for Image','Image Store','a4df3881-4d7e-4b3b-a71a-3380bdebf371','Y',TO_TIMESTAMP('2016-08-18 21:03:42','YYYY-MM-DD HH24:MI:SS'),0,100,100,0,'D')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:05:23 PM MYT
|
||||||
|
INSERT INTO AD_Column (AD_Column_ID,SeqNoSelection,IsSyncDatabase,Version,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,Updated,IsUpdateable,ColumnName,Description,Name,IsAllowCopy,IsActive,CreatedBy,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,AD_Org_ID,Created,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID) VALUES (212831,0,'N',0,'N','N','N',0,'N',22,'N','N','N','Y','a3d7a4ea-9d2e-4da6-b48f-7ee5242719ee',TO_TIMESTAMP('2016-08-18 21:05:07','YYYY-MM-DD HH24:MI:SS'),'Y','StorageImage_ID','Storage provider for Image','Image Store','Y','Y',100,100,'N','N',0,0,TO_TIMESTAMP('2016-08-18 21:05:07','YYYY-MM-DD HH24:MI:SS'),'D','N','N','N',203038,18,200023,227)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:05:59 PM MYT
|
||||||
|
UPDATE AD_Column SET FKConstraintType='N', FKConstraintName='StorageImage_ADClientInfo',Updated=TO_TIMESTAMP('2016-08-18 21:05:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=212831
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:05:59 PM MYT
|
||||||
|
ALTER TABLE AD_ClientInfo ADD COLUMN StorageImage_ID NUMERIC(10) DEFAULT NULL
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:06:00 PM MYT
|
||||||
|
ALTER TABLE AD_ClientInfo ADD CONSTRAINT StorageImage_ADClientInfo FOREIGN KEY (StorageImage_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:07:51 PM MYT
|
||||||
|
INSERT INTO AD_Field (SortNo,AD_Field_ID,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,IsReadOnly,AD_Org_ID,Updated,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,CreatedBy,UpdatedBy,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,Created,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,AD_Tab_ID) VALUES (0,204272,'N',0,'N','N',1020,'Y','N',0,TO_TIMESTAMP('2016-08-18 21:07:45','YYYY-MM-DD HH24:MI:SS'),'Storage provider for Image','Image Store','471cc623-0460-4b6a-8e24-74055858ce8a','Y','N',100,100,'Y','Y',1020,1,'N',0,TO_TIMESTAMP('2016-08-18 21:07:45','YYYY-MM-DD HH24:MI:SS'),2,1,'N','N',212831,'D',169)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:08:51 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=120, IsDisplayed='Y', XPosition=1,Updated=TO_TIMESTAMP('2016-08-18 21:08:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204272
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:08:51 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=125,Updated=TO_TIMESTAMP('2016-08-18 21:08:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202532
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Aug 18, 2016 9:08:51 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=130,Updated=TO_TIMESTAMP('2016-08-18 21:08:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202533
|
||||||
|
;
|
||||||
|
|
||||||
|
SELECT register_migration_script('201608191500_Ticket_1006528.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
|
@ -298,6 +298,10 @@ public class InOutGenerate extends SvrProcess
|
||||||
createLine (order, line, toDeliver, null, false);
|
createLine (order, line, toDeliver, null, false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (product == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Stored Product
|
// Stored Product
|
||||||
String MMPolicy = product.getMMPolicy();
|
String MMPolicy = product.getMMPolicy();
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.compiere.model.ImageDBStorageImpl">
|
||||||
|
<implementation class="org.compiere.model.ImageDBStorageImpl"/>
|
||||||
|
<service>
|
||||||
|
<provide interface="org.compiere.model.IImageStore"/>
|
||||||
|
</service>
|
||||||
|
<property name="method" type="String" value="DB"/>
|
||||||
|
</scr:component>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.compiere.model.ImageFileStorageImpl">
|
||||||
|
<implementation class="org.compiere.model.ImageFileStorageImpl"/>
|
||||||
|
<service>
|
||||||
|
<provide interface="org.compiere.model.IImageStore"/>
|
||||||
|
</service>
|
||||||
|
<property name="method" type="String" value="FileSystem"/>
|
||||||
|
</scr:component>
|
|
@ -113,4 +113,13 @@ public class ArchiveDB implements IArchiveStore {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPendingFlush() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush(MArchive archive, MStorageProvider prov) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ public class ArchiveFileSystem implements IArchiveStore {
|
||||||
|
|
||||||
private static final CLogger log = CLogger.getCLogger(ArchiveFileSystem.class);
|
private static final CLogger log = CLogger.getCLogger(ArchiveFileSystem.class);
|
||||||
|
|
||||||
|
//temporary buffer when AD_Archive_ID=0;
|
||||||
|
private byte[] buffer;
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.compiere.model.IArchiveStore#loadLOBData(org.compiere.model.MArchive, org.compiere.model.MStorageProvider)
|
* @see org.compiere.model.IArchiveStore#loadLOBData(org.compiere.model.MArchive, org.compiere.model.MStorageProvider)
|
||||||
|
@ -63,6 +65,7 @@ public class ArchiveFileSystem implements IArchiveStore {
|
||||||
if ("".equals(archivePathRoot)) {
|
if ("".equals(archivePathRoot)) {
|
||||||
throw new IllegalArgumentException("no attachmentPath defined");
|
throw new IllegalArgumentException("no attachmentPath defined");
|
||||||
}
|
}
|
||||||
|
buffer = null;
|
||||||
byte[] data = archive.getByteData();
|
byte[] data = archive.getByteData();
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -144,24 +147,29 @@ public class ArchiveFileSystem implements IArchiveStore {
|
||||||
* @see org.compiere.model.IArchiveStore#save(org.compiere.model.MArchive, org.compiere.model.MStorageProvider)
|
* @see org.compiere.model.IArchiveStore#save(org.compiere.model.MArchive, org.compiere.model.MStorageProvider)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void save(MArchive archive, MStorageProvider prov,byte[] inflatedData) {
|
public void save(MArchive archive, MStorageProvider prov,byte[] inflatedData) {
|
||||||
String archivePathRoot = getArchivePathRoot(prov);
|
|
||||||
if ("".equals(archivePathRoot)) {
|
|
||||||
throw new IllegalArgumentException("no attachmentPath defined");
|
|
||||||
}
|
|
||||||
if (inflatedData == null || inflatedData.length == 0) {
|
if (inflatedData == null || inflatedData.length == 0) {
|
||||||
throw new IllegalArgumentException("InflatedData is NULL");
|
throw new IllegalArgumentException("InflatedData is NULL");
|
||||||
}
|
}
|
||||||
if(archive.get_ID()==0){
|
if(archive.get_ID()==0){
|
||||||
//set binary data otherwise save will fail
|
//set binary data otherwise save will fail
|
||||||
archive.setByteData(new byte[]{'0'});
|
archive.setByteData(new byte[]{'0'});
|
||||||
if(!archive.save()) {
|
buffer = inflatedData;
|
||||||
throw new IllegalArgumentException("unable to save MArchive");
|
} else {
|
||||||
}
|
write(archive, prov, inflatedData);
|
||||||
}
|
}
|
||||||
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
}
|
||||||
|
|
||||||
|
private void write(MArchive archive, MStorageProvider prov,
|
||||||
|
byte[] inflatedData) {
|
||||||
BufferedOutputStream out = null;
|
BufferedOutputStream out = null;
|
||||||
try {
|
try {
|
||||||
|
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
|
||||||
|
String archivePathRoot = getArchivePathRoot(prov);
|
||||||
|
if ("".equals(archivePathRoot)) {
|
||||||
|
throw new IllegalArgumentException("no attachmentPath defined");
|
||||||
|
}
|
||||||
// create destination folder
|
// create destination folder
|
||||||
StringBuilder msgfile = new StringBuilder().append(archivePathRoot)
|
StringBuilder msgfile = new StringBuilder().append(archivePathRoot)
|
||||||
.append(archive.getArchivePathSnippet());
|
.append(archive.getArchivePathSnippet());
|
||||||
|
@ -203,6 +211,7 @@ public class ArchiveFileSystem implements IArchiveStore {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.log(Level.SEVERE, "saveLOBData", e);
|
log.log(Level.SEVERE, "saveLOBData", e);
|
||||||
archive.setByteData(null);
|
archive.setByteData(null);
|
||||||
|
throw new RuntimeException(e);
|
||||||
} finally {
|
} finally {
|
||||||
if(out != null){
|
if(out != null){
|
||||||
try {
|
try {
|
||||||
|
@ -210,7 +219,6 @@ public class ArchiveFileSystem implements IArchiveStore {
|
||||||
} catch (Exception e) { }
|
} catch (Exception e) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getArchivePathRoot(MStorageProvider prov) {
|
private String getArchivePathRoot(MStorageProvider prov) {
|
||||||
|
@ -233,7 +241,7 @@ public class ArchiveFileSystem implements IArchiveStore {
|
||||||
throw new IllegalArgumentException("no attachmentPath defined");
|
throw new IllegalArgumentException("no attachmentPath defined");
|
||||||
}
|
}
|
||||||
StringBuilder msgfile = new StringBuilder().append(archivePathRoot)
|
StringBuilder msgfile = new StringBuilder().append(archivePathRoot)
|
||||||
.append(archive.getArchivePathSnippet()).append(archive.get_ID()).append(".pdf");
|
.append(archive.getArchivePathSnippet()).append(archive.getAD_Archive_ID()).append(".pdf");
|
||||||
|
|
||||||
File file=new File(msgfile.toString());
|
File file=new File(msgfile.toString());
|
||||||
if (file !=null && file.exists()) {
|
if (file !=null && file.exists()) {
|
||||||
|
@ -245,4 +253,17 @@ public class ArchiveFileSystem implements IArchiveStore {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPendingFlush() {
|
||||||
|
return buffer != null && buffer.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush(MArchive archive, MStorageProvider prov) {
|
||||||
|
if (buffer != null && buffer.length > 0) {
|
||||||
|
write(archive, prov, buffer);
|
||||||
|
buffer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,7 +288,8 @@ public class AttachmentFileSystem implements IAttachmentStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attach.m_items.remove(index);
|
attach.m_items.remove(index);
|
||||||
attach.saveEx(); // must save here as the operation cannot be rolled back on filesystem
|
if (attach.get_ID() > 0) // the attachment has not been deleted
|
||||||
|
attach.saveEx(); // must save here as the operation cannot be rolled back on filesystem
|
||||||
if (log.isLoggable(Level.CONFIG)) log.config("Index=" + index + " - NewSize=" + attach.m_items.size());
|
if (log.isLoggable(Level.CONFIG)) log.config("Index=" + index + " - NewSize=" + attach.m_items.size());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,4 +21,7 @@ public interface IArchiveStore {
|
||||||
|
|
||||||
public boolean deleteArchive(MArchive archive, MStorageProvider prov);
|
public boolean deleteArchive(MArchive archive, MStorageProvider prov);
|
||||||
|
|
||||||
|
public boolean isPendingFlush();
|
||||||
|
|
||||||
|
public void flush(MArchive archive,MStorageProvider prov);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: iDempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2012 Trek Global *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program 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 this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.compiere.model;
|
||||||
|
|
||||||
|
public interface IImageStore {
|
||||||
|
|
||||||
|
public byte[] load(MImage image, MStorageProvider prov);
|
||||||
|
|
||||||
|
public void save(MImage image, MStorageProvider prov, byte[] inflatedData);
|
||||||
|
|
||||||
|
public boolean delete(MImage image, MStorageProvider prov);
|
||||||
|
|
||||||
|
public boolean isPendingFlush();
|
||||||
|
|
||||||
|
public void flush(MImage image,MStorageProvider prov);
|
||||||
|
}
|
|
@ -449,6 +449,21 @@ public interface I_AD_ClientInfo
|
||||||
|
|
||||||
public org.compiere.model.I_AD_StorageProvider getStorageArchive() throws RuntimeException;
|
public org.compiere.model.I_AD_StorageProvider getStorageArchive() throws RuntimeException;
|
||||||
|
|
||||||
|
/** Column name StorageImage_ID */
|
||||||
|
public static final String COLUMNNAME_StorageImage_ID = "StorageImage_ID";
|
||||||
|
|
||||||
|
/** Set Image Store.
|
||||||
|
* Storage provider for Image
|
||||||
|
*/
|
||||||
|
public void setStorageImage_ID (int StorageImage_ID);
|
||||||
|
|
||||||
|
/** Get Image Store.
|
||||||
|
* Storage provider for Image
|
||||||
|
*/
|
||||||
|
public int getStorageImage_ID();
|
||||||
|
|
||||||
|
public org.compiere.model.I_AD_StorageProvider getStorageImage() throws RuntimeException;
|
||||||
|
|
||||||
/** Column name Updated */
|
/** Column name Updated */
|
||||||
public static final String COLUMNNAME_Updated = "Updated";
|
public static final String COLUMNNAME_Updated = "Updated";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: iDempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2012 Trek Global *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program 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 this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.compiere.model;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.zip.Deflater;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ImageDBStorageImpl implements IImageStore {
|
||||||
|
|
||||||
|
|
||||||
|
private final CLogger log = CLogger.getCLogger(getClass());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] load(MImage image, MStorageProvider prov) {
|
||||||
|
byte[] deflatedData = image.getByteData();
|
||||||
|
if (deflatedData == null)
|
||||||
|
return null;
|
||||||
|
//
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine("ZipSize=" + deflatedData.length);
|
||||||
|
if (deflatedData.length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
byte[] inflatedData = null;
|
||||||
|
try {
|
||||||
|
ZipInputStream zip = null;
|
||||||
|
ZipEntry entry = null;
|
||||||
|
if (MSysConfig.getBooleanValue(MSysConfig.IMAGE_DB_STORAGE_SAVE_AS_ZIP, false)) {
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(deflatedData);
|
||||||
|
zip = new ZipInputStream(in);
|
||||||
|
entry = zip.getNextEntry();
|
||||||
|
}
|
||||||
|
if (entry != null)
|
||||||
|
{
|
||||||
|
// just one entry per zip
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
byte[] buffer = new byte[2048];
|
||||||
|
int length = zip.read(buffer);
|
||||||
|
while (length != -1) {
|
||||||
|
out.write(buffer, 0, length);
|
||||||
|
length = zip.read(buffer);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
inflatedData = out.toByteArray();
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine("Size=" + inflatedData.length + " - zip=" + entry.getCompressedSize()
|
||||||
|
+ "(" + entry.getSize() + ") "
|
||||||
|
+ (entry.getCompressedSize() * 100 / entry.getSize()) + "%");
|
||||||
|
} else {
|
||||||
|
//not zip stream, legacy data, or saving as raw
|
||||||
|
inflatedData = deflatedData;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "", e);
|
||||||
|
inflatedData = null;
|
||||||
|
}
|
||||||
|
return inflatedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(MImage image, MStorageProvider prov, byte[] inflatedData) {
|
||||||
|
if (inflatedData == null || inflatedData.length == 0) {
|
||||||
|
image.setByteData(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
byte[] deflatedData = null;
|
||||||
|
if (MSysConfig.getBooleanValue(MSysConfig.IMAGE_DB_STORAGE_SAVE_AS_ZIP, false)) {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zip = new ZipOutputStream(out);
|
||||||
|
zip.setMethod(ZipOutputStream.DEFLATED);
|
||||||
|
zip.setLevel(Deflater.BEST_COMPRESSION);
|
||||||
|
zip.setComment("idempiere");
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
ZipEntry entry = new ZipEntry(image.getName());
|
||||||
|
entry.setTime(System.currentTimeMillis());
|
||||||
|
entry.setMethod(ZipEntry.DEFLATED);
|
||||||
|
zip.putNextEntry(entry);
|
||||||
|
zip.write(inflatedData, 0, inflatedData.length);
|
||||||
|
zip.closeEntry();
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine(entry.getCompressedSize() + " (" + entry.getSize() + ") "
|
||||||
|
+ (entry.getCompressedSize() * 100 / entry.getSize()) + "%");
|
||||||
|
//
|
||||||
|
// zip.finish();
|
||||||
|
zip.close();
|
||||||
|
deflatedData = out.toByteArray();
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine("Length=" + inflatedData.length);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "saveLOBData", e);
|
||||||
|
deflatedData = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
deflatedData = inflatedData;
|
||||||
|
}
|
||||||
|
image.setByteData(deflatedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean delete(MImage image, MStorageProvider prov) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPendingFlush() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush(MImage image, MStorageProvider prov) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,267 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: iDempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2012 Trek Global *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program 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 this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
package org.compiere.model;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.transform.Source;
|
||||||
|
import javax.xml.transform.dom.DOMSource;
|
||||||
|
import javax.xml.transform.Result;
|
||||||
|
import javax.xml.transform.Transformer;
|
||||||
|
import javax.xml.transform.TransformerFactory;
|
||||||
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.Util;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.NamedNodeMap;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ImageFileStorageImpl implements IImageStore {
|
||||||
|
|
||||||
|
private String IMAGE_FOLDER_PLACEHOLDER = "%IMAGE_FOLDER%";
|
||||||
|
|
||||||
|
private final CLogger log = CLogger.getCLogger(getClass());
|
||||||
|
|
||||||
|
//temporary buffer when AD_Image_ID=0
|
||||||
|
private byte[] buffer = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] load(MImage image, MStorageProvider prov) {
|
||||||
|
String imagePathRoot = getImagePathRoot(prov);
|
||||||
|
if ("".equals(imagePathRoot)) {
|
||||||
|
throw new IllegalArgumentException("no path defined");
|
||||||
|
}
|
||||||
|
buffer = null;
|
||||||
|
byte[] data = image.getByteData();
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
final Document document = builder.parse(new ByteArrayInputStream(data));
|
||||||
|
final NodeList entries = document.getElementsByTagName("entry");
|
||||||
|
if(entries.getLength()!=1){
|
||||||
|
log.severe("no image entry found");
|
||||||
|
}
|
||||||
|
final Node entryNode = entries.item(0);
|
||||||
|
final NamedNodeMap attributes = entryNode.getAttributes();
|
||||||
|
final Node fileNode = attributes.getNamedItem("file");
|
||||||
|
if(fileNode==null ){
|
||||||
|
log.severe("no filename for entry");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String filePath = fileNode.getNodeValue();
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine("filePath: " + filePath);
|
||||||
|
if(filePath!=null){
|
||||||
|
filePath = filePath.replaceFirst(IMAGE_FOLDER_PLACEHOLDER, imagePathRoot.replaceAll("\\\\","\\\\\\\\"));
|
||||||
|
//just to be shure...
|
||||||
|
String replaceSeparator = File.separator;
|
||||||
|
if(!replaceSeparator.equals("/")){
|
||||||
|
replaceSeparator = "\\\\";
|
||||||
|
}
|
||||||
|
filePath = filePath.replaceAll("/", replaceSeparator);
|
||||||
|
filePath = filePath.replaceAll("\\\\", replaceSeparator);
|
||||||
|
}
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine("filePath: " + filePath);
|
||||||
|
final File file = new File(filePath);
|
||||||
|
if (file.exists()) {
|
||||||
|
// read files into byte[]
|
||||||
|
final byte[] dataEntry = new byte[(int) file.length()];
|
||||||
|
try {
|
||||||
|
final FileInputStream fileInputStream = new FileInputStream(file);
|
||||||
|
fileInputStream.read(dataEntry);
|
||||||
|
fileInputStream.close();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
log.severe("File Not Found.");
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
log.severe("Error Reading The File.");
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
return dataEntry;
|
||||||
|
} else {
|
||||||
|
log.severe("file not found: " + file.getAbsolutePath());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SAXException sxe) {
|
||||||
|
// Error generated during parsing)
|
||||||
|
Exception x = sxe;
|
||||||
|
if (sxe.getException() != null)
|
||||||
|
x = sxe.getException();
|
||||||
|
x.printStackTrace();
|
||||||
|
log.severe(x.getMessage());
|
||||||
|
|
||||||
|
} catch (ParserConfigurationException pce) {
|
||||||
|
// Parser with specified options can't be built
|
||||||
|
pce.printStackTrace();
|
||||||
|
log.severe(pce.getMessage());
|
||||||
|
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// I/O error
|
||||||
|
ioe.printStackTrace();
|
||||||
|
log.severe(ioe.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(MImage image, MStorageProvider prov,byte[] inflatedData) {
|
||||||
|
if (inflatedData == null || inflatedData.length == 0) {
|
||||||
|
image.setByteData(null);
|
||||||
|
delete(image, prov);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(image.get_ID()==0){
|
||||||
|
//set binary data otherwise save will fail
|
||||||
|
image.setByteData(new byte[]{'0'});
|
||||||
|
buffer = inflatedData;
|
||||||
|
} else {
|
||||||
|
write(image, prov, inflatedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void write(MImage image, MStorageProvider prov, byte[] inflatedData) {
|
||||||
|
BufferedOutputStream out = null;
|
||||||
|
try {
|
||||||
|
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
|
||||||
|
String imagePathRoot = getImagePathRoot(prov);
|
||||||
|
if ("".equals(imagePathRoot)) {
|
||||||
|
throw new IllegalArgumentException("no storage path defined");
|
||||||
|
}
|
||||||
|
// create destination folder
|
||||||
|
StringBuilder msgfile = new StringBuilder().append(imagePathRoot)
|
||||||
|
.append(image.getImageStoragePath());
|
||||||
|
final File destFolder = new File(msgfile.toString());
|
||||||
|
if (!destFolder.exists()) {
|
||||||
|
if (!destFolder.mkdirs()) {
|
||||||
|
log.warning("unable to create folder: " + destFolder.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write to path
|
||||||
|
msgfile = new StringBuilder().append(imagePathRoot).append(File.separator)
|
||||||
|
.append(image.getImageStoragePath()).append(image.get_ID());
|
||||||
|
final File destFile = new File(msgfile.toString());
|
||||||
|
|
||||||
|
out = new BufferedOutputStream(new FileOutputStream(destFile));
|
||||||
|
out.write(inflatedData);
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
//create xml entry
|
||||||
|
final DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
final Document document = builder.newDocument();
|
||||||
|
final Element root = document.createElement("image");
|
||||||
|
document.appendChild(root);
|
||||||
|
document.setXmlStandalone(true);
|
||||||
|
final Element entry = document.createElement("entry");
|
||||||
|
StringBuilder msgsat = new StringBuilder(IMAGE_FOLDER_PLACEHOLDER).append(image.getImageStoragePath()).append(image.get_ID());
|
||||||
|
entry.setAttribute("file", msgsat.toString());
|
||||||
|
root.appendChild(entry);
|
||||||
|
final Source source = new DOMSource(document);
|
||||||
|
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
final Result result = new StreamResult(bos);
|
||||||
|
final Transformer xformer = TransformerFactory.newInstance().newTransformer();
|
||||||
|
xformer.transform(source, result);
|
||||||
|
final byte[] xmlData = bos.toByteArray();
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine(bos.toString());
|
||||||
|
//store xml in db
|
||||||
|
image.setByteData(xmlData);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "saveLOBData", e);
|
||||||
|
image.setByteData(null);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if(out != null){
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (Exception e) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getImagePathRoot(MStorageProvider prov) {
|
||||||
|
String imagePathRoot = prov.getFolder();
|
||||||
|
if (imagePathRoot == null)
|
||||||
|
imagePathRoot = "";
|
||||||
|
if (Util.isEmpty(imagePathRoot)) {
|
||||||
|
log.severe("no image Path defined");
|
||||||
|
} else if (!imagePathRoot.endsWith(File.separator)){
|
||||||
|
imagePathRoot = imagePathRoot + File.separator;
|
||||||
|
log.fine(imagePathRoot);
|
||||||
|
}
|
||||||
|
return imagePathRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean delete(MImage image, MStorageProvider prov) {
|
||||||
|
String imagePathRoot = getImagePathRoot(prov);
|
||||||
|
if ("".equals(imagePathRoot)) {
|
||||||
|
throw new IllegalArgumentException("no image path defined");
|
||||||
|
}
|
||||||
|
StringBuilder msgfile = new StringBuilder().append(imagePathRoot)
|
||||||
|
.append(image.getImageStoragePath()).append(image.getAD_Image_ID());
|
||||||
|
|
||||||
|
File file=new File(msgfile.toString());
|
||||||
|
if (file !=null && file.exists()) {
|
||||||
|
if (!file.delete()) {
|
||||||
|
log.warning("unable to delete " + file.getAbsolutePath());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPendingFlush() {
|
||||||
|
return buffer != null && buffer.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush(MImage image, MStorageProvider prov) {
|
||||||
|
if (buffer != null && buffer.length > 0) {
|
||||||
|
write(image, prov, buffer);
|
||||||
|
buffer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ public class MArchive extends X_AD_Archive {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 3217541537768473865L;
|
private static final long serialVersionUID = -9116541441191978777L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Archives
|
* Get Archives
|
||||||
|
@ -269,7 +269,8 @@ public class MArchive extends X_AD_Archive {
|
||||||
return true;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
protected boolean beforeDelete ()
|
@Override
|
||||||
|
protected boolean postDelete()
|
||||||
{
|
{
|
||||||
IArchiveStore prov = provider.getArchiveStore();
|
IArchiveStore prov = provider.getArchiveStore();
|
||||||
if (prov != null)
|
if (prov != null)
|
||||||
|
@ -278,4 +279,11 @@ public class MArchive extends X_AD_Archive {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void saveNew_afterSetID()
|
||||||
|
{
|
||||||
|
IArchiveStore prov = provider.getArchiveStore();
|
||||||
|
if (prov != null && prov.isPendingFlush())
|
||||||
|
prov.flush(this,provider);
|
||||||
|
}
|
||||||
} // MArchive
|
} // MArchive
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class MAttachment extends X_AD_Attachment
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -8261865873158774665L;
|
private static final long serialVersionUID = 6596285414376249694L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -502,28 +502,20 @@ public class MAttachment extends X_AD_Attachment
|
||||||
return saveLOBData(); // save in BinaryData
|
return saveLOBData(); // save in BinaryData
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
/**
|
|
||||||
* Executed before Delete operation.
|
|
||||||
* @return true if record can be deleted
|
|
||||||
*/
|
|
||||||
protected boolean beforeDelete ()
|
|
||||||
{
|
|
||||||
return deleteLOBData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete Entry Data in Zip File format
|
* Delete Entry Data in Zip File format
|
||||||
* @return true if saved
|
* @return true if saved
|
||||||
*/
|
*/
|
||||||
private boolean deleteLOBData()
|
@Override
|
||||||
|
protected boolean postDelete()
|
||||||
{
|
{
|
||||||
if (m_items == null)
|
if (m_items == null)
|
||||||
loadLOBData();
|
loadLOBData();
|
||||||
IAttachmentStore prov = provider.getAttachmentStore();
|
IAttachmentStore prov = provider.getAttachmentStore();
|
||||||
if (prov != null)
|
if (prov != null)
|
||||||
return prov.delete(this,provider);
|
return prov.delete(this,provider);
|
||||||
return false;
|
return true;
|
||||||
} // beforeDelete
|
} // postDelete
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Test
|
* Test
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class MBPartner extends X_C_BPartner
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -255154524310324997L;
|
private static final long serialVersionUID = 5534148976588041343L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Empty Template Business Partner
|
* Get Empty Template Business Partner
|
||||||
|
@ -1006,4 +1006,16 @@ public class MBPartner extends X_C_BPartner
|
||||||
return success;
|
return success;
|
||||||
} // afterDelete
|
} // afterDelete
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean postDelete() {
|
||||||
|
if (getLogo_ID() > 0) {
|
||||||
|
MImage img = new MImage(getCtx(), getLogo_ID(), get_TrxName());
|
||||||
|
if (!img.delete(true)) {
|
||||||
|
log.warning("Associated image could not be deleted for bpartner - AD_Image_ID=" + getLogo_ID());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // MBPartner
|
} // MBPartner
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.awt.Image;
|
||||||
import java.awt.MediaTracker;
|
import java.awt.MediaTracker;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
|
@ -49,6 +50,8 @@ public class MImage extends X_AD_Image
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -7361463683427300715L;
|
private static final long serialVersionUID = -7361463683427300715L;
|
||||||
|
|
||||||
|
private MStorageProvider provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get MImage from Cache
|
* Get MImage from Cache
|
||||||
* @param ctx context
|
* @param ctx context
|
||||||
|
@ -84,6 +87,7 @@ public class MImage extends X_AD_Image
|
||||||
super (ctx, AD_Image_ID, trxName);
|
super (ctx, AD_Image_ID, trxName);
|
||||||
if (AD_Image_ID < 1)
|
if (AD_Image_ID < 1)
|
||||||
setName("-");
|
setName("-");
|
||||||
|
initImageStoreDetails(ctx, trxName);
|
||||||
} // MImage
|
} // MImage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +99,7 @@ public class MImage extends X_AD_Image
|
||||||
public MImage (Properties ctx, ResultSet rs, String trxName)
|
public MImage (Properties ctx, ResultSet rs, String trxName)
|
||||||
{
|
{
|
||||||
super(ctx, rs, trxName);
|
super(ctx, rs, trxName);
|
||||||
|
initImageStoreDetails(ctx, trxName);
|
||||||
} // MImage
|
} // MImage
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,20 +238,31 @@ public class MImage extends X_AD_Image
|
||||||
* Set Binary Data
|
* Set Binary Data
|
||||||
* @param BinaryData data
|
* @param BinaryData data
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void setBinaryData (byte[] BinaryData)
|
public void setBinaryData (byte[] BinaryData)
|
||||||
{
|
{
|
||||||
m_image = null;
|
m_image = null;
|
||||||
m_icon = null;
|
m_icon = null;
|
||||||
super.setBinaryData (BinaryData);
|
IImageStore prov = provider.getImageStore();
|
||||||
|
if (prov != null)
|
||||||
|
prov.save(this,provider,BinaryData);
|
||||||
} // setBinaryData
|
} // setBinaryData
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBinaryData() {
|
||||||
|
IImageStore prov = provider.getImageStore();
|
||||||
|
if (prov != null)
|
||||||
|
return prov.load(this,provider);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Data
|
* Get Data
|
||||||
* @return data
|
* @return data
|
||||||
*/
|
*/
|
||||||
public byte[] getData()
|
public byte[] getData()
|
||||||
{
|
{
|
||||||
byte[] data = super.getBinaryData ();
|
byte[] data = getBinaryData ();
|
||||||
if (data != null)
|
if (data != null)
|
||||||
return data;
|
return data;
|
||||||
// From URL
|
// From URL
|
||||||
|
@ -311,5 +327,47 @@ public class MImage extends X_AD_Image
|
||||||
setAD_Org_ID(0);
|
setAD_Org_ID(0);
|
||||||
return true;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
public String getImageStoragePath() {
|
||||||
|
StringBuilder path = new StringBuilder("AD_Image").append(File.separator)
|
||||||
|
.append(this.getAD_Client_ID()).append(File.separator);
|
||||||
|
return path.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ctx
|
||||||
|
* @param trxName
|
||||||
|
*/
|
||||||
|
private void initImageStoreDetails(Properties ctx, String trxName) {
|
||||||
|
MClientInfo clientInfo = MClientInfo.get(ctx);
|
||||||
|
provider=new MStorageProvider(ctx, clientInfo.getStorageImage_ID(), trxName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStorageProvider(MStorageProvider p) {
|
||||||
|
provider = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getByteData(){
|
||||||
|
return super.getBinaryData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setByteData(byte[] BinaryData){
|
||||||
|
super.setBinaryData(BinaryData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean postDelete() {
|
||||||
|
IImageStore prov = provider.getImageStore();
|
||||||
|
if (prov != null)
|
||||||
|
return prov.delete(this,provider);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void saveNew_afterSetID()
|
||||||
|
{
|
||||||
|
IImageStore prov = provider.getImageStore();
|
||||||
|
if (prov != null && prov.isPendingFlush())
|
||||||
|
prov.flush(this, provider);
|
||||||
|
}
|
||||||
} // MImage
|
} // MImage
|
||||||
|
|
|
@ -28,11 +28,10 @@ import java.util.Properties;
|
||||||
*/
|
*/
|
||||||
public class MPOSKey extends X_C_POSKey
|
public class MPOSKey extends X_C_POSKey
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -5810613982853803837L;
|
private static final long serialVersionUID = 2595668386249398840L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard Constructor
|
* Standard Constructor
|
||||||
|
@ -56,4 +55,16 @@ public class MPOSKey extends X_C_POSKey
|
||||||
super(ctx, rs, trxName);
|
super(ctx, rs, trxName);
|
||||||
} // MPOSKey
|
} // MPOSKey
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean postDelete() {
|
||||||
|
if (getAD_Image_ID() > 0) {
|
||||||
|
MImage img = new MImage(getCtx(), getAD_Image_ID(), get_TrxName());
|
||||||
|
if (!img.delete(true)) {
|
||||||
|
log.warning("Associated image could not be deleted for POS Key - AD_Image_ID=" + getAD_Image_ID());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // MPOSKey
|
} // MPOSKey
|
||||||
|
|
|
@ -63,4 +63,16 @@ public class MStorageProvider extends X_AD_StorageProvider {
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IImageStore getImageStore() {
|
||||||
|
ServiceQuery query=new ServiceQuery();
|
||||||
|
String method = this.getMethod();
|
||||||
|
if (method == null)
|
||||||
|
method = "DB";
|
||||||
|
query.put("method", method);
|
||||||
|
IImageStore store = Service.locator().locate(IImageStore.class, query).getService();
|
||||||
|
if (store == null) {
|
||||||
|
throw new AdempiereException("No image storage provider found");
|
||||||
|
}
|
||||||
|
return store;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class MSysConfig extends X_AD_SysConfig
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -4014355086112902334L;
|
private static final long serialVersionUID = -9208749663408576569L;
|
||||||
|
|
||||||
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
|
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
|
||||||
public static final String ALERT_SEND_ATTACHMENT_AS_XLS = "ALERT_SEND_ATTACHMENT_AS_XLS";
|
public static final String ALERT_SEND_ATTACHMENT_AS_XLS = "ALERT_SEND_ATTACHMENT_AS_XLS";
|
||||||
|
@ -99,6 +99,7 @@ public class MSysConfig extends X_AD_SysConfig
|
||||||
public static final String HTML_REPORT_THEME = "HTML_REPORT_THEME";
|
public static final String HTML_REPORT_THEME = "HTML_REPORT_THEME";
|
||||||
public static final String IBAN_VALIDATION = "IBAN_VALIDATION";
|
public static final String IBAN_VALIDATION = "IBAN_VALIDATION";
|
||||||
public static final String IDENTIFIER_SEPARATOR = "IDENTIFIER_SEPARATOR";
|
public static final String IDENTIFIER_SEPARATOR = "IDENTIFIER_SEPARATOR";
|
||||||
|
public static final String IMAGE_DB_STORAGE_SAVE_AS_ZIP = "IMAGE_DB_STORAGE_SAVE_AS_ZIP";
|
||||||
public static final String INFO_DEFAULTSELECTED = "INFO_DEFAULTSELECTED";
|
public static final String INFO_DEFAULTSELECTED = "INFO_DEFAULTSELECTED";
|
||||||
public static final String INFO_DOUBLECLICKTOGGLESSELECTION = "INFO_DOUBLECLICKTOGGLESSELECTION";
|
public static final String INFO_DOUBLECLICKTOGGLESSELECTION = "INFO_DOUBLECLICKTOGGLESSELECTION";
|
||||||
public static final String Invoice_ReverseUseNewNumber = "Invoice_ReverseUseNewNumber";
|
public static final String Invoice_ReverseUseNewNumber = "Invoice_ReverseUseNewNumber";
|
||||||
|
|
|
@ -33,7 +33,6 @@ import javax.mail.internet.AddressException;
|
||||||
import javax.mail.internet.InternetAddress;
|
import javax.mail.internet.InternetAddress;
|
||||||
|
|
||||||
import org.adempiere.exceptions.DBException;
|
import org.adempiere.exceptions.DBException;
|
||||||
import org.codehaus.groovy.classgen.GeneratorContext;
|
|
||||||
import org.compiere.util.CCache;
|
import org.compiere.util.CCache;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
|
@ -59,7 +58,7 @@ public class MUser extends X_AD_User
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 7996468236476384128L;
|
private static final long serialVersionUID = 1366564982801896588L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get active Users of BPartner
|
* Get active Users of BPartner
|
||||||
|
@ -1105,4 +1104,17 @@ public class MUser extends X_AD_User
|
||||||
}
|
}
|
||||||
return super.afterSave(newRecord, success);
|
return super.afterSave(newRecord, success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean postDelete() {
|
||||||
|
if (getAD_Image_ID() > 0) {
|
||||||
|
MImage img = new MImage(getCtx(), getAD_Image_ID(), get_TrxName());
|
||||||
|
if (!img.delete(true)) {
|
||||||
|
log.warning("Associated image could not be deleted for user - AD_Image_ID=" + getAD_Image_ID());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // MUser
|
} // MUser
|
||||||
|
|
|
@ -110,7 +110,7 @@ public abstract class PO
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -1743619574547406959L;
|
private static final long serialVersionUID = -1330388218446118451L;
|
||||||
|
|
||||||
public static final String LOCAL_TRX_PREFIX = "POSave";
|
public static final String LOCAL_TRX_PREFIX = "POSave";
|
||||||
|
|
||||||
|
@ -2782,6 +2782,7 @@ public abstract class PO
|
||||||
}
|
}
|
||||||
m_IDs[0] = Integer.valueOf(no);
|
m_IDs[0] = Integer.valueOf(no);
|
||||||
set_ValueNoCheck(m_KeyColumns[0], m_IDs[0]);
|
set_ValueNoCheck(m_KeyColumns[0], m_IDs[0]);
|
||||||
|
saveNew_afterSetID();
|
||||||
}
|
}
|
||||||
//uuid secondary key
|
//uuid secondary key
|
||||||
int uuidIndex = p_info.getColumnIndex(getUUIDColumnName());
|
int uuidIndex = p_info.getColumnIndex(getUUIDColumnName());
|
||||||
|
@ -3096,6 +3097,13 @@ public abstract class PO
|
||||||
return 0;
|
return 0;
|
||||||
} // saveNew_getID
|
} // saveNew_getID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call after ID have been assigned for new record
|
||||||
|
*/
|
||||||
|
protected void saveNew_afterSetID()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Single/Multi Key Where Clause
|
* Create Single/Multi Key Where Clause
|
||||||
|
@ -3496,6 +3504,10 @@ public abstract class PO
|
||||||
// Reset
|
// Reset
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
if (!postDelete()) {
|
||||||
|
log.warning("postDelete failed");
|
||||||
|
}
|
||||||
|
|
||||||
//osgi event handler
|
//osgi event handler
|
||||||
Event event = EventManager.newEvent(IEventTopics.PO_POST_DELETE, this);
|
Event event = EventManager.newEvent(IEventTopics.PO_POST_DELETE, this);
|
||||||
EventManager.getInstance().postEvent(event);
|
EventManager.getInstance().postEvent(event);
|
||||||
|
@ -3595,6 +3607,14 @@ public abstract class PO
|
||||||
return success;
|
return success;
|
||||||
} // afterDelete
|
} // afterDelete
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed after the Delete operation is committed in the database.
|
||||||
|
* @return true if post delete is a success
|
||||||
|
*/
|
||||||
|
protected boolean postDelete()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert (missing) Translation Records
|
* Insert (missing) Translation Records
|
||||||
|
|
|
@ -109,15 +109,27 @@ public class PO_Record
|
||||||
if (s_cascades[i] != AD_Table_ID)
|
if (s_cascades[i] != AD_Table_ID)
|
||||||
{
|
{
|
||||||
Object[] params = new Object[]{Integer.valueOf(AD_Table_ID), Integer.valueOf(Record_ID)};
|
Object[] params = new Object[]{Integer.valueOf(AD_Table_ID), Integer.valueOf(Record_ID)};
|
||||||
StringBuffer sql = new StringBuffer ("DELETE FROM ")
|
if (s_cascadeNames[i].equals(X_AD_Attachment.Table_Name) || s_cascadeNames[i].equals(X_AD_Archive.Table_Name))
|
||||||
.append(s_cascadeNames[i])
|
{
|
||||||
.append(" WHERE AD_Table_ID=? AND Record_ID=?");
|
Query query = new Query(Env.getCtx(), s_cascadeNames[i], "AD_Table_ID=? AND Record_ID=?", trxName);
|
||||||
int no = DB.executeUpdate(sql.toString(), params, false, trxName);
|
List<PO> list = query.setParameters(params).list();
|
||||||
if (no > 0) {
|
for(PO po : list)
|
||||||
if (log.isLoggable(Level.CONFIG)) log.config(s_cascadeNames[i] + " (" + AD_Table_ID + "/" + Record_ID + ") #" + no);
|
{
|
||||||
} else if (no < 0) {
|
po.deleteEx(true);
|
||||||
log.severe(s_cascadeNames[i] + " (" + AD_Table_ID + "/" + Record_ID + ") #" + no);
|
}
|
||||||
return false;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StringBuffer sql = new StringBuffer ("DELETE FROM ")
|
||||||
|
.append(s_cascadeNames[i])
|
||||||
|
.append(" WHERE AD_Table_ID=? AND Record_ID=?");
|
||||||
|
int no = DB.executeUpdate(sql.toString(), params, false, trxName);
|
||||||
|
if (no > 0) {
|
||||||
|
if (log.isLoggable(Level.CONFIG)) log.config(s_cascadeNames[i] + " (" + AD_Table_ID + "/" + Record_ID + ") #" + no);
|
||||||
|
} else if (no < 0) {
|
||||||
|
log.severe(s_cascadeNames[i] + " (" + AD_Table_ID + "/" + Record_ID + ") #" + no);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class X_AD_ClientInfo extends PO implements I_AD_ClientInfo, I_Persistent
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 20191121L;
|
private static final long serialVersionUID = 20200226L;
|
||||||
|
|
||||||
/** Standard Constructor */
|
/** Standard Constructor */
|
||||||
public X_AD_ClientInfo (Properties ctx, int AD_ClientInfo_ID, String trxName)
|
public X_AD_ClientInfo (Properties ctx, int AD_ClientInfo_ID, String trxName)
|
||||||
|
@ -767,4 +767,32 @@ public class X_AD_ClientInfo extends PO implements I_AD_ClientInfo, I_Persistent
|
||||||
return 0;
|
return 0;
|
||||||
return ii.intValue();
|
return ii.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public org.compiere.model.I_AD_StorageProvider getStorageImage() throws RuntimeException
|
||||||
|
{
|
||||||
|
return (org.compiere.model.I_AD_StorageProvider)MTable.get(getCtx(), org.compiere.model.I_AD_StorageProvider.Table_Name)
|
||||||
|
.getPO(getStorageImage_ID(), get_TrxName()); }
|
||||||
|
|
||||||
|
/** Set Image Store.
|
||||||
|
@param StorageImage_ID
|
||||||
|
Storage provider for Image
|
||||||
|
*/
|
||||||
|
public void setStorageImage_ID (int StorageImage_ID)
|
||||||
|
{
|
||||||
|
if (StorageImage_ID < 1)
|
||||||
|
set_Value (COLUMNNAME_StorageImage_ID, null);
|
||||||
|
else
|
||||||
|
set_Value (COLUMNNAME_StorageImage_ID, Integer.valueOf(StorageImage_ID));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get Image Store.
|
||||||
|
@return Storage provider for Image
|
||||||
|
*/
|
||||||
|
public int getStorageImage_ID ()
|
||||||
|
{
|
||||||
|
Integer ii = (Integer)get_Value(COLUMNNAME_StorageImage_ID);
|
||||||
|
if (ii == null)
|
||||||
|
return 0;
|
||||||
|
return ii.intValue();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -49,6 +49,7 @@ Import-Package: groovy.transform.stc;version="2.4.7",
|
||||||
org.jfree.data.time,
|
org.jfree.data.time,
|
||||||
org.jfree.util,
|
org.jfree.util,
|
||||||
org.osgi.framework;version="1.7.0",
|
org.osgi.framework;version="1.7.0",
|
||||||
|
org.osgi.framework.wiring;version="1.2.0",
|
||||||
org.osgi.service.component.annotations;version="1.3.0",
|
org.osgi.service.component.annotations;version="1.3.0",
|
||||||
org.osgi.service.event;version="1.3.0",
|
org.osgi.service.event;version="1.3.0",
|
||||||
org.osgi.util.tracker;version="1.5.0",
|
org.osgi.util.tracker;version="1.5.0",
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
|
|
||||||
private boolean commitResponse() throws IOException {
|
private boolean commitResponse() throws IOException {
|
||||||
AtmosphereResource resource = this.resource.getAndSet(null);
|
AtmosphereResource resource = this.resource.getAndSet(null);
|
||||||
if (resource != null && resource.isSuspended()) {
|
if (resource != null) {
|
||||||
resource.resume();
|
resource.resume();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ public class AtmosphereServerPush implements ServerPush {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!resource.isSuspended()) {
|
if (!resource.isSuspended()) {
|
||||||
resource.suspend(-1);
|
resource.suspend();
|
||||||
}
|
}
|
||||||
this.resource.set(resource);
|
this.resource.set(resource);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ import org.atmosphere.cpr.AtmosphereRequest;
|
||||||
import org.atmosphere.cpr.AtmosphereResource;
|
import org.atmosphere.cpr.AtmosphereResource;
|
||||||
import org.atmosphere.cpr.AtmosphereResourceEvent;
|
import org.atmosphere.cpr.AtmosphereResourceEvent;
|
||||||
import org.atmosphere.cpr.AtmosphereResponse;
|
import org.atmosphere.cpr.AtmosphereResponse;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.zkoss.zk.ui.Desktop;
|
import org.zkoss.zk.ui.Desktop;
|
||||||
import org.zkoss.zk.ui.Session;
|
import org.zkoss.zk.ui.Session;
|
||||||
import org.zkoss.zk.ui.http.WebManager;
|
import org.zkoss.zk.ui.http.WebManager;
|
||||||
|
@ -41,6 +43,8 @@ import org.zkoss.zk.ui.sys.WebAppCtrl;
|
||||||
*/
|
*/
|
||||||
public class ZkAtmosphereHandler implements AtmosphereHandler {
|
public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
}
|
}
|
||||||
|
@ -49,6 +53,8 @@ public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
if (session.getWebApp() instanceof WebAppCtrl) {
|
if (session.getWebApp() instanceof WebAppCtrl) {
|
||||||
WebAppCtrl webAppCtrl = (WebAppCtrl) session.getWebApp();
|
WebAppCtrl webAppCtrl = (WebAppCtrl) session.getWebApp();
|
||||||
Desktop desktop = webAppCtrl.getDesktopCache(session).getDesktopIfAny(dtid);
|
Desktop desktop = webAppCtrl.getDesktopCache(session).getDesktopIfAny(dtid);
|
||||||
|
if (desktop == null)
|
||||||
|
log.warn("Could not find desktop: " + dtid);
|
||||||
return new Either<String, Desktop>("Could not find desktop", desktop);
|
return new Either<String, Desktop>("Could not find desktop", desktop);
|
||||||
}
|
}
|
||||||
return new Either<String, Desktop>("Webapp does not implement WebAppCtrl", null);
|
return new Either<String, Desktop>("Webapp does not implement WebAppCtrl", null);
|
||||||
|
@ -101,10 +107,12 @@ public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
|
|
||||||
private Either<String, Session> getSession(AtmosphereResource resource, HttpServletRequest request) {
|
private Either<String, Session> getSession(AtmosphereResource resource, HttpServletRequest request) {
|
||||||
Session session = WebManager.getSession(resource.getAtmosphereConfig().getServletContext(), request, false);
|
Session session = WebManager.getSession(resource.getAtmosphereConfig().getServletContext(), request, false);
|
||||||
if (session == null)
|
if (session == null) {
|
||||||
|
log.warn("Could not find session: " + request.getRequestURI());
|
||||||
return new Either<String, Session>("Could not find session", null);
|
return new Either<String, Session>("Could not find session", null);
|
||||||
else
|
} else {
|
||||||
return new Either<String, Session>(null, session);
|
return new Either<String, Session>(null, session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -116,6 +124,7 @@ public class ZkAtmosphereHandler implements AtmosphereHandler {
|
||||||
Either<String, AtmosphereServerPush> serverPushEither = getServerPush(resource);
|
Either<String, AtmosphereServerPush> serverPushEither = getServerPush(resource);
|
||||||
String error = serverPushEither.getLeftValue();
|
String error = serverPushEither.getLeftValue();
|
||||||
if (error != null && serverPushEither.getRightValue() == null) {
|
if (error != null && serverPushEither.getRightValue() == null) {
|
||||||
|
log.warn("Bad Request. Error="+error+", Request="+resource.getRequest().getRequestURI());
|
||||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
response.getWriter().write(error);
|
response.getWriter().write(error);
|
||||||
response.getWriter().flush();
|
response.getWriter().flush();
|
||||||
|
|
|
@ -178,6 +178,10 @@ public class WImageEditor extends WEditor
|
||||||
//
|
//
|
||||||
ValueChangeEvent vce = new ValueChangeEvent(WImageEditor.this, gridField.getColumnName(), oldValue, newValue);
|
ValueChangeEvent vce = new ValueChangeEvent(WImageEditor.this, gridField.getColumnName(), oldValue, newValue);
|
||||||
fireValueChange(vce);
|
fireValueChange(vce);
|
||||||
|
if (oldValue == null && newValue != null && getGridField() != null && getGridField().getGridTab() != null) {
|
||||||
|
// save automatically when creating a new image
|
||||||
|
getGridField().getGridTab().dataSave(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ import org.compiere.util.Util;
|
||||||
import org.osgi.framework.Bundle;
|
import org.osgi.framework.Bundle;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
import org.osgi.framework.BundleException;
|
import org.osgi.framework.BundleException;
|
||||||
|
import org.osgi.framework.wiring.BundleRevision;
|
||||||
import org.zkoss.util.media.AMedia;
|
import org.zkoss.util.media.AMedia;
|
||||||
import org.zkoss.zhtml.Pre;
|
import org.zkoss.zhtml.Pre;
|
||||||
import org.zkoss.zhtml.Text;
|
import org.zkoss.zhtml.Text;
|
||||||
|
@ -445,16 +446,37 @@ public class AboutWindow extends Window implements EventListener<Event> {
|
||||||
if (bundle == null)
|
if (bundle == null)
|
||||||
return;
|
return;
|
||||||
int state = bundle.getState();
|
int state = bundle.getState();
|
||||||
|
boolean isFragment = false;
|
||||||
|
BundleRevision rev = bundle.adapt(BundleRevision.class);
|
||||||
|
if (rev != null) {
|
||||||
|
isFragment = (rev.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
boolean hasFragments = false;
|
||||||
|
if (!isFragment) {
|
||||||
|
if (rev.getWiring() != null) {
|
||||||
|
if (rev.getWiring().getProvidedWires(BundleRevision.HOST_NAMESPACE).size() > 0) {
|
||||||
|
hasFragments = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
if (bundle.getBundleId() == 0) {
|
if (bundle.getBundleId() == 0) {
|
||||||
// bundle 0 cannot be stopped
|
// bundle 0 cannot be stopped
|
||||||
} else if (state == Bundle.ACTIVE) {
|
} else if (state == Bundle.ACTIVE) {
|
||||||
pluginActions.getItemAtIndex(PLUGIN_ACTION_STOP).setVisible(true);
|
pluginActions.getItemAtIndex(PLUGIN_ACTION_STOP).setVisible(true);
|
||||||
} else if (state == Bundle.RESOLVED) {
|
} else if (state == Bundle.RESOLVED) {
|
||||||
pluginActions.getItemAtIndex(PLUGIN_ACTION_START).setVisible(true);
|
if (!isFragment) {
|
||||||
|
pluginActions.getItemAtIndex(PLUGIN_ACTION_START).setVisible(true);
|
||||||
|
}
|
||||||
} else if (state == Bundle.INSTALLED) {
|
} else if (state == Bundle.INSTALLED) {
|
||||||
// no options yet for installed
|
if (!isFragment) {
|
||||||
|
pluginActions.getItemAtIndex(PLUGIN_ACTION_START).setVisible(true);
|
||||||
|
}
|
||||||
} else if (state == Bundle.STARTING) {
|
} else if (state == Bundle.STARTING) {
|
||||||
// no options yet for starting
|
if (!isFragment) {
|
||||||
|
pluginActions.getItemAtIndex(PLUGIN_ACTION_START).setVisible(true);
|
||||||
|
}
|
||||||
} else if (state == Bundle.STOPPING) {
|
} else if (state == Bundle.STOPPING) {
|
||||||
// no options yet for stopping
|
// no options yet for stopping
|
||||||
} else if (state == Bundle.UNINSTALLED) {
|
} else if (state == Bundle.UNINSTALLED) {
|
||||||
|
@ -466,8 +488,7 @@ public class AboutWindow extends Window implements EventListener<Event> {
|
||||||
Bundle retValue = null;
|
Bundle retValue = null;
|
||||||
int idx = pluginsTable.getSelectedIndex();
|
int idx = pluginsTable.getSelectedIndex();
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
Integer selectedPlugin = (Integer) pluginsTable.getModel().getDataAt(idx, 1);
|
Vector<Object> pluginVector = pluginData.get(idx);
|
||||||
Vector<Object> pluginVector = pluginData.get(selectedPlugin);
|
|
||||||
int pluginId = ((IDColumn)pluginVector.get(0)).getRecord_ID();
|
int pluginId = ((IDColumn)pluginVector.get(0)).getRecord_ID();
|
||||||
BundleContext bundleCtx = WebUIActivator.getBundleContext();
|
BundleContext bundleCtx = WebUIActivator.getBundleContext();
|
||||||
retValue = bundleCtx.getBundle(pluginId);
|
retValue = bundleCtx.getBundle(pluginId);
|
||||||
|
@ -505,6 +526,7 @@ public class AboutWindow extends Window implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshPluginTable() {
|
private void refreshPluginTable() {
|
||||||
|
int idx = pluginsTable.getSelectedIndex();
|
||||||
pluginsTable.getModel().removeAll(pluginData);
|
pluginsTable.getModel().removeAll(pluginData);
|
||||||
pluginData.removeAllElements();
|
pluginData.removeAllElements();
|
||||||
|
|
||||||
|
@ -521,6 +543,7 @@ public class AboutWindow extends Window implements EventListener<Event> {
|
||||||
}
|
}
|
||||||
ListModelTable model = new ListModelTable(pluginData);
|
ListModelTable model = new ListModelTable(pluginData);
|
||||||
pluginsTable.setData(model, pluginColumnNames);
|
pluginsTable.setData(model, pluginColumnNames);
|
||||||
|
pluginsTable.setSelectedIndex(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Tabpanel createInfo() {
|
protected Tabpanel createInfo() {
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
trace: false,
|
trace: false,
|
||||||
ajaxOptions: {
|
ajaxOptions: {
|
||||||
url: zk.ajaxURI("/comet", {au: true}),
|
url: zk.ajaxURI("/comet", {au: true}),
|
||||||
type: "GET",
|
type: "POST",
|
||||||
cache: false,
|
cache: false,
|
||||||
async: true,
|
async: true,
|
||||||
global: false,
|
global: false,
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
this.ajaxOptions.data = { dtid: this.desktop.id };
|
this.ajaxOptions.data = { dtid: this.desktop.id };
|
||||||
this.ajaxOptions.timeout = this.timeout;
|
this.ajaxOptions.timeout = this.timeout;
|
||||||
|
this.ajaxOptions.url = zk.ajaxURI("/comet", {au: true,desktop:this.desktop.id,ignoreSession:false}),
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
var me = this;
|
var me = this;
|
||||||
this.ajaxOptions.error = function(jqxhr, textStatus, errorThrown) {
|
this.ajaxOptions.error = function(jqxhr, textStatus, errorThrown) {
|
||||||
|
|
Loading…
Reference in New Issue