IDEMPIERE-1379:Info Windows should have their own icon/image
move manage imageCache to ManageImageCache improve imageCache for + don't load local image to cache + handle exception when wrong link or disconnect network + when many MImage has same extenal url, just load one time + tab for "info window" has same icon when display in daskboad view
This commit is contained in:
parent
e99cff2f02
commit
517f0299e1
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.adempiere.webui.adwindow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -35,9 +34,7 @@ import org.compiere.model.MToolBarButton;
|
|||
import org.compiere.model.MToolBarButtonRestrict;
|
||||
import org.compiere.model.MWindow;
|
||||
import org.compiere.model.X_AD_ToolBarButton;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.Env;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
|
||||
/**
|
||||
|
@ -59,8 +56,6 @@ public class ADWindow extends AbstractUIPart
|
|||
|
||||
private Component windowPanelComponent;
|
||||
private MImage image;
|
||||
|
||||
private static final CCache<Integer, AImage> imageCache = new CCache<Integer, AImage>(null, "WindowImageCache", 5, false);
|
||||
|
||||
private Map<Integer, List<String>> tabToolbarRestricMap = new HashMap<Integer, List<String>>();
|
||||
|
||||
|
@ -129,23 +124,6 @@ public class ADWindow extends AbstractUIPart
|
|||
return image;
|
||||
}
|
||||
|
||||
public AImage getAImage() throws IOException {
|
||||
MImage image = getMImage();
|
||||
AImage aImage = null;
|
||||
if (image != null) {
|
||||
synchronized (imageCache) {
|
||||
aImage = imageCache.get(image.getAD_Image_ID());
|
||||
}
|
||||
if (aImage == null) {
|
||||
aImage = new AImage(image.getName(), image.getData());
|
||||
synchronized (imageCache) {
|
||||
imageCache.put(image.getAD_Image_ID(), aImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
return aImage;
|
||||
}
|
||||
|
||||
protected Component doCreatePart(Component parent)
|
||||
{
|
||||
windowPanelComponent = windowContent.createPart(parent);
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
|
||||
package org.adempiere.webui.component;
|
||||
|
||||
import org.adempiere.webui.adwindow.ADWindow;
|
||||
import org.adempiere.webui.util.ManageImageCache;
|
||||
import org.compiere.model.MImage;
|
||||
import org.compiere.model.MInfoWindow;
|
||||
import org.zkoss.image.Image;
|
||||
import org.zkoss.zul.impl.LabelImageElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
|
||||
|
@ -40,6 +47,11 @@ public class Tab extends org.zkoss.zul.Tab
|
|||
|
||||
}
|
||||
|
||||
public void setDecorateInfo (DecorateInfo decorateInfo){
|
||||
if (decorateInfo != null)
|
||||
decorateInfo.decorate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
Tabpanel tp = (Tabpanel) getLinkedPanel();
|
||||
|
@ -48,4 +60,50 @@ public class Tab extends org.zkoss.zul.Tab
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* class contain decorate info
|
||||
* at the moment, has only image info
|
||||
* at the moment, it's use to transfer decorate info from info window, standard window, report, process,... to tab
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public static class DecorateInfo {
|
||||
private String imageKey;
|
||||
private String imageIntenalUrl;
|
||||
|
||||
public void decorate (LabelImageElement comp){
|
||||
if (imageIntenalUrl != null)
|
||||
comp.setImage(imageIntenalUrl);
|
||||
else if (imageKey != null){
|
||||
Image ico = ManageImageCache.instance().getImage(imageKey);
|
||||
if (ico != null)
|
||||
comp.setImageContent(ico);
|
||||
}
|
||||
}
|
||||
|
||||
public DecorateInfo (MImage imageData){
|
||||
imageIntenalUrl = ManageImageCache.getImageInternalUrl(imageData);
|
||||
if (imageIntenalUrl == null)
|
||||
imageKey = ManageImageCache.instance().loadImage(imageData);
|
||||
}
|
||||
|
||||
public DecorateInfo (String imagePath){
|
||||
imageIntenalUrl = ManageImageCache.getImageInternalUrl(imagePath);
|
||||
if (imageIntenalUrl == null)
|
||||
imageKey = imagePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for create decorate info from adWindow info
|
||||
* @param adWindow
|
||||
* @return
|
||||
*/
|
||||
public static DecorateInfo get (ADWindow adWindow){
|
||||
return adWindow == null?null:new DecorateInfo(adWindow.getMImage());
|
||||
}
|
||||
|
||||
public static DecorateInfo get (MInfoWindow mInfo){
|
||||
return mInfo==null?null:new DecorateInfo(mInfo.getImageURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,7 +243,7 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
|
|||
windowContainer.createPart(windowArea);
|
||||
|
||||
homeTab = new Tabpanel();
|
||||
windowContainer.addWindow(homeTab, Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Home")), false);
|
||||
windowContainer.addWindow(homeTab, Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Home")), false, null);
|
||||
homeTab.getLinkedTab().setSclass("desktop-hometab");
|
||||
homeTab.setSclass("desktop-home-tabpanel");
|
||||
BusyDialog busyDialog = new BusyDialog();
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
*****************************************************************************/
|
||||
package org.adempiere.webui.desktop;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.adempiere.util.Callback;
|
||||
|
@ -22,6 +21,7 @@ import org.adempiere.webui.adwindow.ADWindow;
|
|||
import org.adempiere.webui.apps.ProcessDialog;
|
||||
import org.adempiere.webui.apps.wf.WFPanel;
|
||||
import org.adempiere.webui.component.DesktopTabpanel;
|
||||
import org.adempiere.webui.component.Tab.DecorateInfo;
|
||||
import org.adempiere.webui.component.Tabbox;
|
||||
import org.adempiere.webui.component.Tabpanel;
|
||||
import org.adempiere.webui.component.Window;
|
||||
|
@ -32,11 +32,11 @@ import org.adempiere.webui.panel.InfoPanel;
|
|||
import org.adempiere.webui.part.WindowContainer;
|
||||
import org.adempiere.webui.window.FDialog;
|
||||
import org.adempiere.webui.window.WTask;
|
||||
import org.compiere.model.MInfoWindow;
|
||||
import org.compiere.model.MQuery;
|
||||
import org.compiere.model.MTask;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.wf.MWorkflow;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.util.media.AMedia;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
|
@ -73,7 +73,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
String title = pd.getTitle();
|
||||
pd.setTitle(null);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, title, true);
|
||||
windowContainer.addWindow(tabPanel, title, true, null);
|
||||
Events.postEvent(ProcessDialog.ON_INITIAL_FOCUS_EVENT, pd, null);
|
||||
}
|
||||
return pd;
|
||||
|
@ -93,7 +93,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
//do not show window title when open as tab
|
||||
form.setTitle(null);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, form.getFormName(), true);
|
||||
windowContainer.addWindow(tabPanel, form.getFormName(), true, null);
|
||||
form.focus();
|
||||
} else {
|
||||
form.setAttribute(Window.MODE_KEY, form.getWindowMode());
|
||||
|
@ -117,7 +117,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
String title = infoPanel.getTitle();
|
||||
infoPanel.setTitle(null);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, title, true);
|
||||
windowContainer.addWindow(tabPanel, title, true, DecorateInfo.get(MInfoWindow.get(infoId, null)));
|
||||
infoPanel.focus();
|
||||
} else {
|
||||
FDialog.error(0, "NotValid");
|
||||
|
@ -135,7 +135,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
DesktopTabpanel tabPanel = new DesktopTabpanel();
|
||||
p.setParent(tabPanel);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, p.getWorkflow().get_Translation(MWorkflow.COLUMNNAME_Name), true);
|
||||
windowContainer.addWindow(tabPanel, p.getWorkflow().get_Translation(MWorkflow.COLUMNNAME_Name), true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,7 +160,8 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
final DesktopTabpanel tabPanel = new DesktopTabpanel();
|
||||
String id = AdempiereIdGenerator.escapeId(adWindow.getTitle());
|
||||
tabPanel.setId(id+"_"+adWindow.getADWindowContent().getWindowNo());
|
||||
final Tab tab = windowContainer.addWindow(tabPanel, adWindow.getTitle(), true);
|
||||
final Tab tab = windowContainer.addWindow(tabPanel, adWindow.getTitle(), true, DecorateInfo.get(adWindow));
|
||||
|
||||
tab.setClosable(false);
|
||||
final OpenWindowRunnable runnable = new OpenWindowRunnable(adWindow, tab, tabPanel, callback);
|
||||
preOpenNewTab();
|
||||
|
@ -233,7 +234,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
Tabpanel tabPanel = new Tabpanel();
|
||||
window.setParent(tabPanel);
|
||||
preOpenNewTab();
|
||||
windowContainer.addWindow(tabPanel, title, closeable);
|
||||
windowContainer.addWindow(tabPanel, title, closeable, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +246,7 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
final ADWindow wnd = new ADWindow(Env.getCtx(), AD_Window_ID, query);
|
||||
|
||||
final DesktopTabpanel tabPanel = new DesktopTabpanel();
|
||||
final Tab tab = windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true);
|
||||
final Tab tab = windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, wnd.getTitle(), true, true, DecorateInfo.get(wnd));
|
||||
tab.setClosable(false);
|
||||
final OpenWindowRunnable runnable = new OpenWindowRunnable(wnd, tab, tabPanel, null);
|
||||
preOpenNewTab();
|
||||
|
@ -277,9 +278,9 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
window.setTitle(null);
|
||||
preOpenNewTab();
|
||||
if (Window.INSERT_NEXT.equals(window.getAttribute(Window.INSERT_POSITION_KEY)))
|
||||
windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, title, true, true);
|
||||
windowContainer.insertAfter(windowContainer.getSelectedTab(), tabPanel, title, true, true, null);
|
||||
else
|
||||
windowContainer.addWindow(tabPanel, title, true);
|
||||
windowContainer.addWindow(tabPanel, title, true, null);
|
||||
if (window instanceof IHelpContext)
|
||||
Events.sendEvent(new Event(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, window));
|
||||
}
|
||||
|
@ -381,13 +382,6 @@ public abstract class TabbedDesktop extends AbstractDesktop {
|
|||
public void run() {
|
||||
if (adWindow.createPart(tabPanel) != null ) {
|
||||
tab.setClosable(true);
|
||||
if (adWindow.getMImage() != null) {
|
||||
try {
|
||||
AImage aImage = adWindow.getAImage();
|
||||
tab.setImageContent(aImage);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.onCallback(adWindow);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.List;
|
|||
|
||||
import org.adempiere.webui.component.Menupopup;
|
||||
import org.adempiere.webui.component.Tab;
|
||||
import org.adempiere.webui.component.Tab.DecorateInfo;
|
||||
import org.adempiere.webui.component.Tabbox;
|
||||
import org.adempiere.webui.component.Tabpanel;
|
||||
import org.adempiere.webui.component.Tabpanels;
|
||||
|
@ -101,15 +102,63 @@ public class WindowContainer extends AbstractUIPart
|
|||
return tabbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #addWindow(Component, String, boolean, DecorateInfo)}
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @return
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable){
|
||||
return addWindow(comp, title, closeable, true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #addWindow(Component, String, boolean, boolean, DecorateInfo)}
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @param enable
|
||||
* @return
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, boolean enable) {
|
||||
return addWindow(comp, title, closeable, true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #insertBefore(Tab, Component, String, boolean, boolean, DecorateInfo)}
|
||||
* @param refTab
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @param enable
|
||||
* @return
|
||||
*/
|
||||
public Tab insertBefore(Tab refTab, Component comp, String title, boolean closeable, boolean enable){
|
||||
return insertBefore(refTab, comp, title, closeable, enable, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated keep for compatible, replace by {@link #insertAfter(Component, String, boolean, boolean, DecorateInfo)}
|
||||
* @param refTab
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
* @param enable
|
||||
* @return
|
||||
*/
|
||||
public Tab insertAfter(Tab refTab, Component comp, String title, boolean closeable, boolean enable){
|
||||
return insertAfter(refTab, comp, title, closeable, enable, null);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param comp
|
||||
* @param title
|
||||
* @param closeable
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable)
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, DecorateInfo decorateInfo)
|
||||
{
|
||||
return addWindow(comp, title, closeable, true);
|
||||
return addWindow(comp, title, closeable, true, decorateInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,9 +168,9 @@ public class WindowContainer extends AbstractUIPart
|
|||
* @param closeable
|
||||
* @param enable
|
||||
*/
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, boolean enable)
|
||||
public Tab addWindow(Component comp, String title, boolean closeable, boolean enable, DecorateInfo decorateInfo)
|
||||
{
|
||||
return insertBefore(null, comp, title, closeable, enable);
|
||||
return insertBefore(null, comp, title, closeable, enable, decorateInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,9 +181,10 @@ public class WindowContainer extends AbstractUIPart
|
|||
* @param closeable
|
||||
* @param enable
|
||||
*/
|
||||
public Tab insertBefore(Tab refTab, Component comp, String title, boolean closeable, boolean enable)
|
||||
public Tab insertBefore(Tab refTab, Component comp, String title, boolean closeable, boolean enable, DecorateInfo decorateInfo)
|
||||
{
|
||||
final Tab tab = new Tab();
|
||||
tab.setDecorateInfo(decorateInfo);
|
||||
if (title != null)
|
||||
{
|
||||
setTabTitle(title, tab);
|
||||
|
@ -318,12 +368,12 @@ public class WindowContainer extends AbstractUIPart
|
|||
* @param closeable
|
||||
* @param enable
|
||||
*/
|
||||
public Tab insertAfter(Tab refTab, Component comp, String title, boolean closeable, boolean enable)
|
||||
public Tab insertAfter(Tab refTab, Component comp, String title, boolean closeable, boolean enable, DecorateInfo decorateInfo)
|
||||
{
|
||||
if (refTab == null)
|
||||
return addWindow(comp, title, closeable, enable);
|
||||
return addWindow(comp, title, closeable, enable, decorateInfo);
|
||||
else
|
||||
return insertBefore((Tab)refTab.getNextSibling(), comp, title, closeable, enable);
|
||||
return insertBefore((Tab)refTab.getNextSibling(), comp, title, closeable, enable, decorateInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
/**********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
**********************************************************************/
|
||||
|
||||
package org.adempiere.webui.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.base.Core;
|
||||
import org.compiere.model.MImage;
|
||||
import org.compiere.util.CCache;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Env;
|
||||
import org.zkoss.image.AImage;
|
||||
import org.zkoss.image.Image;
|
||||
|
||||
/**
|
||||
* Normal image can come from inside system or from outside system.
|
||||
* with image from outside for performance we will cache it.
|
||||
* this class for manage image cache and provide help function relate
|
||||
* @author hieplq
|
||||
*
|
||||
*/
|
||||
public class ManageImageCache {
|
||||
|
||||
protected static transient CLogger log = CLogger.getCLogger (ManageImageCache.class);
|
||||
/**
|
||||
* this cache is don't expire, if must restart cache when has update image.
|
||||
* better use a timer, example reset cache after 10 minute has update. it help user can change a batch of image and reset one time.
|
||||
*/
|
||||
private final CCache<String, Image> imageCache = new CCache<String, Image>(null, "WindowImageCache", 50, 0, false);
|
||||
|
||||
private static ManageImageCache instance;
|
||||
|
||||
/**
|
||||
* get instance
|
||||
* @return
|
||||
*/
|
||||
public static ManageImageCache instance(){
|
||||
if (instance == null){
|
||||
synchronized (ManageImageCache.class){
|
||||
if (instance == null)
|
||||
instance = new ManageImageCache();
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* investigate image path of MImage, if path is a internal return internal url other return null
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public static String getImageInternalUrl (MImage image){
|
||||
if (image == null)
|
||||
return null;
|
||||
return getImageInternalUrl(image.getImageURL());
|
||||
}
|
||||
|
||||
/**
|
||||
* investigate image path, if path is a internal return internal url other return null
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
public static String getImageInternalUrl (String url){
|
||||
if (url == null || url.trim().length() == 0 || url.indexOf("://") > 0)
|
||||
return null;
|
||||
|
||||
URL urlRsource = Core.getResourceFinder().getResource(url);
|
||||
return urlRsource == null?null:urlRsource.getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load image from url
|
||||
* @param imagePath
|
||||
* @return
|
||||
*/
|
||||
protected static byte [] loadImageData (String imagePath){
|
||||
byte [] data = null;
|
||||
|
||||
URLConnection conn;
|
||||
try {
|
||||
URL url = new URL(imagePath);
|
||||
conn = url.openConnection();
|
||||
|
||||
conn.setUseCaches(false);
|
||||
InputStream is = conn.getInputStream();
|
||||
byte[] buffer = new byte[1024*8]; // 8kB
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
int length = -1;
|
||||
while ((length = is.read(buffer)) != -1)
|
||||
os.write(buffer, 0, length);
|
||||
is.close();
|
||||
data = os.toByteArray();
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
if (log.isLoggable(Level.CONFIG)) log.config (e.toString());
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* if image is don't in cache, load it (imagePath can id of MImage)
|
||||
* @param imagePath
|
||||
* @return image load from path. null when has any exception
|
||||
*/
|
||||
public Image getImage(String imagePath){
|
||||
if (imagePath == null || imagePath.trim().length() == 0)
|
||||
return null;
|
||||
|
||||
Image aImage = null;
|
||||
boolean hasCache = false;
|
||||
synchronized (imageCache) {
|
||||
hasCache = imageCache.containsKey(imagePath);
|
||||
}
|
||||
|
||||
if (!hasCache) {
|
||||
try{
|
||||
int mImageId = Integer.parseInt(imagePath);
|
||||
loadImage(MImage.get(Env.getCtx(), mImageId));
|
||||
}catch (NumberFormatException ex){
|
||||
loadExtend(imagePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
synchronized (imageCache) {
|
||||
aImage = imageCache.get(imagePath);
|
||||
}
|
||||
|
||||
return aImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* if MImage contain extend image or binary image data, load it into cache and return key
|
||||
* other return null
|
||||
* @param mImage
|
||||
* @return
|
||||
*/
|
||||
public String loadImage (MImage mImage){
|
||||
if (mImage == null)
|
||||
return null;
|
||||
|
||||
boolean hasCache = false;
|
||||
String strId = String.valueOf(mImage.get_ID());
|
||||
synchronized (imageCache) {
|
||||
hasCache = imageCache.containsKey(strId);
|
||||
}
|
||||
|
||||
if(hasCache){
|
||||
return strId;
|
||||
}
|
||||
|
||||
if (mImage.getBinaryData() != null){
|
||||
synchronized (imageCache) {
|
||||
Image loadImage = null;
|
||||
try {
|
||||
loadImage = new AImage (mImage.getName(), mImage.getBinaryData());
|
||||
} catch (IOException e) {
|
||||
// do nothing treat image as null
|
||||
}
|
||||
imageCache.put(String.valueOf(mImage.get_ID()), loadImage);
|
||||
}
|
||||
return strId;
|
||||
}else if (mImage.getImageURL() != null && mImage.getImageURL().trim().length() > 0 && getImageInternalUrl(mImage.getImageURL()) == null){
|
||||
synchronized (imageCache) {
|
||||
hasCache = imageCache.containsKey(mImage.getImageURL());
|
||||
}
|
||||
if (!hasCache){
|
||||
loadExtend (mImage.getImageURL());
|
||||
}
|
||||
return mImage.getImageURL();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* load extend image into cache
|
||||
* @param imagePath
|
||||
*/
|
||||
protected void loadExtend (String imagePath){
|
||||
byte[] data = loadImageData(imagePath);
|
||||
AImage aImage = null;
|
||||
// when can't load image (by incorrect url or disconnect or any exception, just set image as null
|
||||
if (data != null)
|
||||
try {
|
||||
aImage = new AImage(imagePath, data);
|
||||
} catch (IOException e) {
|
||||
aImage = null;
|
||||
}
|
||||
|
||||
synchronized (imageCache) {
|
||||
imageCache.put(imagePath, aImage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@ package org.adempiere.webui.util;
|
|||
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.adempiere.base.IResourceFinder;
|
||||
import org.adempiere.webui.WebUIActivator;
|
||||
|
@ -40,6 +41,7 @@ public class WebUIResourceFinder implements IResourceFinder {
|
|||
return WebUIActivator.getBundleContext().getBundle().findEntries(path, pattern, false);
|
||||
}
|
||||
|
||||
protected Pattern patternOnlyName = Pattern.compile("\\w+\\.\\w+");
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
if ("images/iDempiereHR.png".equals(name) || "images/iDempiere.png".equals(name)) {
|
||||
|
@ -47,6 +49,9 @@ public class WebUIResourceFinder implements IResourceFinder {
|
|||
}
|
||||
Enumeration<URL> e = find(name);
|
||||
URL url = e != null && e.hasMoreElements() ? e.nextElement() : null;
|
||||
if (url == null && patternOnlyName.matcher(name).matches()){
|
||||
name = "images/" + name;
|
||||
}
|
||||
if (url == null && name.startsWith("org/compiere/images")) {
|
||||
String t = name.substring("org/compiere/".length());
|
||||
t = ThemeManager.getThemeResource(t);
|
||||
|
|
Loading…
Reference in New Issue