Bug 277498: [DT Skinning] Images not available to CSS from JARed plug-in
diff --git a/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/TrinidadTagSupportActivator.java b/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/TrinidadTagSupportActivator.java
index 3f42bb6..35aa533 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/TrinidadTagSupportActivator.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/TrinidadTagSupportActivator.java
@@ -13,6 +13,7 @@
 import org.eclipse.core.runtime.ILog;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
+import org.eclipse.jst.jsf.apache.trinidad.tagsupport.dtresourceprovider.TrinidadDTResourceProvider;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
@@ -43,6 +44,7 @@
 	public void start(BundleContext context) throws Exception {
 		super.start(context);
 		plugin = this;
+		TrinidadDTResourceProvider.init();
 	}
 
 	/*
diff --git a/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/dtresourceprovider/TrinidadDTResourceProvider.java b/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/dtresourceprovider/TrinidadDTResourceProvider.java
index 2e414c0..5664642 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/dtresourceprovider/TrinidadDTResourceProvider.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/dtresourceprovider/TrinidadDTResourceProvider.java
@@ -10,10 +10,14 @@
  */
 package org.eclipse.jst.jsf.apache.trinidad.tagsupport.dtresourceprovider;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URL;
-import java.text.MessageFormat;
 import java.util.Collections;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
 
 import org.eclipse.core.runtime.FileLocator;
 import org.eclipse.jst.jsf.apache.trinidad.tagsupport.Messages;
@@ -36,25 +40,124 @@
 	 */
 	public TrinidadDTResourceProvider() {
 		super(ID);
-		addSkin(createSkin(SKIN_MINIMAL, STYLESHEET_MINIMAL, true));
-		addSkin(createSkin(SKIN_SIMPLE, STYLESHEET_SIMPLE, false));
+		addSkin(createSkin(SKIN_MINIMAL, STYLESHEET_MINIMAL_URL, true));
+		addSkin(createSkin(SKIN_SIMPLE, STYLESHEET_SIMPLE_URL, false));
 	}
 
-	private DefaultDTSkin createSkin(String name, String relativePath, boolean isDefault) {
+	private DefaultDTSkin createSkin(String name, URL stylesheetURL, boolean isDefault) {
 		DefaultDTSkin skin = null;
-		URL url = this.getClass().getResource(relativePath);
-		try {
-			url = FileLocator.toFileURL(url);
-			skin = new DefaultDTSkin(name, Collections.singletonList(url));
+		if (stylesheetURL != null) {
+			skin = new DefaultDTSkin(name, Collections.singletonList(stylesheetURL));
 			skin.setDefault(isDefault);
-		} catch(IOException ioe) {
+		} else {
 			TrinidadTagSupportActivator.logError(
-					MessageFormat.format(
-							Messages.TrinidadDTResourceProvider_StyleSheetNotLocated,
-							relativePath),
-					ioe);
+					Messages.TrinidadDTResourceProvider_StyleSheetNotLocated,
+					null);
 		}
 		return skin;
 	}
 
+	//here we try to ensure we can access stylesheets and referenced resources even when JARed
+	private static URL STYLESHEET_MINIMAL_URL;
+	private static URL STYLESHEET_SIMPLE_URL;
+	private static final String DTREZPROV_CACHE_DIRNAME = "dtRezProvCache"; //$NON-NLS-1$
+	private static final String URI_DIRNAME = "myfaces.apache.org_trinidad"; //$NON-NLS-1$
+	private static final String DIR_TO_COPY = "skinning/"; //$NON-NLS-1$
+	/**
+	 * Initializes the class.
+	 */
+	public static void init() {
+		//worst case - we get the stylesheets but no referenced resources (if plug-in is JARed)
+		try {
+			STYLESHEET_MINIMAL_URL = FileLocator.toFileURL(
+					TrinidadDTResourceProvider.class.getResource(STYLESHEET_MINIMAL));
+			STYLESHEET_SIMPLE_URL = FileLocator.toFileURL(
+					TrinidadDTResourceProvider.class.getResource(STYLESHEET_SIMPLE));
+		} catch(IOException ioe) {
+			//nothing to be done
+		}
+		try {
+			File bundleFile = FileLocator.getBundleFile(TrinidadTagSupportActivator.getDefault().getBundle());
+			if (bundleFile.isFile()) {
+				//plug-in is JARed
+				try {
+					File stateLocation = TrinidadTagSupportActivator.getDefault().getStateLocation().toFile();
+					File dtRezProvCacheDir = new File(stateLocation, DTREZPROV_CACHE_DIRNAME);
+					File targetDir = new File(dtRezProvCacheDir, URI_DIRNAME);
+					wipeDir(targetDir);
+					if (targetDir.mkdirs()) {
+						FileInputStream fis = null;
+						JarInputStream jis = null;
+						FileOutputStream fos = null;
+						try {
+							fis = new FileInputStream(bundleFile);
+							jis = new JarInputStream(fis, false);
+							JarEntry jarEntry = jis.getNextJarEntry();
+							while (jarEntry != null) {
+								String name = jarEntry.getName();
+								if (name != null && name.startsWith(DIR_TO_COPY)) {
+									File targetFile = new File(targetDir, name);
+									if (!jarEntry.isDirectory()) {
+										File parentDir = targetFile.getParentFile();
+										if (parentDir != null && !parentDir.exists()) {
+											parentDir.mkdirs();
+										}
+										if (targetFile.createNewFile()) {
+											fos = new FileOutputStream(targetFile);
+											byte[] buf = new byte[1024];
+											int bytesRead = jis.read(buf, 0, 1024);
+											while (bytesRead > 0) {
+												fos.write(buf, 0, bytesRead);
+												bytesRead = jis.read(buf, 0, 1024);
+											}
+										}
+									}
+								}
+								jarEntry = jis.getNextJarEntry();
+							}
+						} catch(IOException ioe) {
+							//do nothing, we fall back on stylesheet without referenced resources
+						} finally {
+							if (fos != null) {
+								fos.close();
+							}
+							if (jis != null) {
+								jis.close();
+							}
+							if (fis != null) {
+								fis.close();
+							}
+						}
+					}
+					File minimalStylesheet = new File(targetDir, STYLESHEET_MINIMAL);
+					if (minimalStylesheet.exists()) {
+						STYLESHEET_MINIMAL_URL = minimalStylesheet.toURL();
+					}
+					File simpleStylesheet = new File(targetDir, STYLESHEET_SIMPLE);
+					if (simpleStylesheet.exists()) {
+						STYLESHEET_SIMPLE_URL = simpleStylesheet.toURL();
+					}
+				} catch(IllegalStateException ise) {
+					//do nothing, we fall back on stylesheet without referenced resources
+				}
+			}
+		} catch(IOException ioe) {
+			//do nothing, we fall back on stylesheet without referenced resources
+		}
+	}
+
+	private static void wipeDir(File targetDir) {
+		if (targetDir != null && targetDir.exists()) {
+			File[] files = targetDir.listFiles();
+			for (File file: files) {
+				if (file.isFile()) {
+					file.delete();
+				} else {
+					wipeDir(file);
+				}
+			}
+			targetDir.delete();
+		}
+	}
+
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/messages.properties b/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/messages.properties
index 931da5f..28fafc3 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/messages.properties
+++ b/jsf/plugins/org.eclipse.jst.jsf.apache.trinidad.tagsupport/src/org/eclipse/jst/jsf/apache/trinidad/tagsupport/messages.properties
@@ -28,4 +28,4 @@
 SelectShuttleOperation_LinkUp=Up
 SelectShuttleOperation_LinkDown=Down
 SelectShuttleOperation_LinkBottom=Bottom
-TrinidadDTResourceProvider_StyleSheetNotLocated=StyleSheet at relative path "{0}" could not be located
\ No newline at end of file
+TrinidadDTResourceProvider_StyleSheetNotLocated=StyleSheet could not be located
\ No newline at end of file