package com.onpositive.gae.baseviewer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
import org.eclipse.jdt.internal.core.PackageFragmentRoot;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Resource;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import com.google.appengine.api.datastore.Blob;
import com.onpositive.commons.ui.dialogs.TitledDialog;
import com.onpositive.semantic.model.binding.Binding;
import com.onpositive.semantic.model.ui.property.editors.CompositeEditor;
public class SerializableBlobVisualizer extends AbstractBlobVisualizer {
public static interface IUpdateBlob {
void updateBlob(byte[] data);
}
private IUpdateBlob updater;
private IJavaProject project;
private Composite parent;
private Composite cc;
private Label classLabel;
private Button showButton;
private Object serialized;
private List<URL> resources = new ArrayList<URL>();
// protected final static String[]
public SerializableBlobVisualizer(IUpdateBlob updater, IJavaProject project) {
this.project = project;
this.updater = updater;
configureResourcesList();
}
public void init(Composite parent) {
this.parent = parent;
GridLayout layout = new GridLayout(1, false);
layout.horizontalSpacing = 0;
layout.verticalSpacing = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
cc = new Composite(parent, SWT.None);
cc.setLayout(layout);
classLabel = new Label(cc, SWT.None);
showButton = new Button(cc, SWT.None);
showButton.setText("edit");
showButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
showButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (serialized != null) {
final Binding parentBnd = new Binding(serialized);
final Class clz = serialized.getClass();
parentBnd.setName(clz.getCanonicalName());
CompositeEditor editor = new CompositeEditor(parentBnd);
EditorUtility.createBindingsForType(clz, parentBnd, editor,
project);
TitledDialog td = new TitledDialog(parentBnd, editor) {
protected void okPressed() {
parentBnd.commit();
if (updater != null) {
Object value = parentBnd.getValue();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(
bos);
oos.writeObject(value);
byte[] array = bos.toByteArray();
updater.updateBlob(array);
} catch (IOException e) {
Activator.log(e);
}
}
super.okPressed();
};
};
td.open();
}
}
});
}
public boolean handleBlob(Blob bl) {
Object obj = parseBlob(bl);
if (obj != null) {
serialized = obj;
classLabel.setText(serialized.getClass().getName());
return true;
}
return false;
}
public void dispose() {
parent = null;
cc.dispose();
classLabel.dispose();
showButton.dispose();
if (serialized != null && (serialized instanceof Resource)) {
((Resource) serialized).dispose();
}
serialized = null;
}
public int getType() {
return SERIALIZABLE_TYPE;
}
protected Object parseBlob(Blob bl) {
try {
URLClassLoader urlCl = new URLClassLoader(
resources.toArray(new URL[resources.size()]));
SpecialObjectInputStream ois = new SpecialObjectInputStream(
new ByteArrayInputStream(bl.getBytes()), urlCl);
Object obj = ois.readObject();
return obj;
} catch (Throwable e) {
}
return null;
}
private class SpecialObjectInputStream extends ObjectInputStream {
private ClassLoader customClassLoader;
public SpecialObjectInputStream(InputStream arg0,
ClassLoader classloader) throws IOException {
super(arg0);
customClassLoader = classloader;
}
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
try {
return customClassLoader.loadClass(desc.getName());
/*
* Class.forName ( desc.getName (), true, customClassLoader );
*/
} catch (ClassNotFoundException e) {
// e.printStackTrace();
// return super.;
}
return super.resolveClass(desc);
}
}
protected void configureResourcesList() {
try {
if (resources == null) {
resources = new ArrayList<URL>();
}
IPath output;
IPath test = project.getPath().makeAbsolute();
output = project.getOutputLocation();
output = output.addTrailingSeparator();
IResource ifil = ResourcesPlugin.getWorkspace().getRoot()
.findMember(output);
URL outputURL = ifil.getLocationURI().toURL();
outputURL = new URL(outputURL.toString() + "/");
resources.add(outputURL);
IJavaElement[] els = project.getChildren();
for (IJavaElement e : els) {
if (!(e instanceof JarPackageFragmentRoot)) {
continue;
}
IResource underlyingResource = e.getUnderlyingResource();
if (underlyingResource != null) {
URI uri = underlyingResource.getLocationURI();
URL tmpRes = uri.toURL();
resources.add(tmpRes);
}
}
} catch (JavaModelException e1) {
Activator.log(e1);
e1.printStackTrace();
} catch (MalformedURLException e) {
Activator.log(e);
e.printStackTrace();
}
}
}