diff options
3 files changed, 123 insertions, 9 deletions
diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/provisional/tasks/core/RepositoryClientManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/provisional/tasks/core/RepositoryClientManager.java index e2f6579f7..23a23f497 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/provisional/tasks/core/RepositoryClientManager.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/provisional/tasks/core/RepositoryClientManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 Tasktop Technologies and others. + * Copyright (c) 2004, 2012 Tasktop Technologies and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,9 +14,13 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; import java.io.Serializable; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; @@ -30,11 +34,40 @@ import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.TaskRepositoryLocationFactory; /** - * TODO: fix class loading problems caused by serialization and make API - * * @author Steffen Pingel */ -abstract class RepositoryClientManager<T, C extends Serializable> implements IRepositoryListener { +public abstract class RepositoryClientManager<T, C extends Serializable> implements IRepositoryListener { + + private class OSGiAwareObjectInputStream extends ObjectInputStream { + + public OSGiAwareObjectInputStream(InputStream in) throws IOException { + super(in); + } + + @Override + protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { + try { + ClassLoader connectorClassloader = getConfigClassloader(); + return connectorClassloader.loadClass(desc.getName()); + } catch (Exception e) { + return super.resolveClass(desc); + } + } + + private ClassLoader getConfigClassloader() { + Class<?> configClazz = getConfigClass(); + ClassLoader connectorClassloader = configClazz.getClassLoader(); + return connectorClassloader; + } + + private Class<?> getConfigClass() { + Class<?> managerClazz = RepositoryClientManager.this.getClass(); + ParameterizedType type = (ParameterizedType) managerClazz.getGenericSuperclass(); + Type[] fieldArgTypes = type.getActualTypeArguments(); + Class<?> configClazz = (Class<?>) fieldArgTypes[1]; + return configClazz; + } + } private final Map<String, T> clientByUrl = new HashMap<String, T>(); @@ -103,7 +136,7 @@ abstract class RepositoryClientManager<T, C extends Serializable> implements IRe ObjectInputStream in = null; try { - in = new ObjectInputStream(new FileInputStream(cacheFile)); + in = new OSGiAwareObjectInputStream(new FileInputStream(cacheFile)); int size = in.readInt(); for (int i = 0; i < size; i++) { String url = (String) in.readObject(); @@ -113,8 +146,7 @@ abstract class RepositoryClientManager<T, C extends Serializable> implements IRe } } } catch (Throwable e) { - StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN, - "The respository configuration cache could not be read", e)); //$NON-NLS-1$ + handleError("The respository configuration cache could not be read", e); //$NON-NLS-1$ } finally { if (in != null) { try { @@ -127,6 +159,10 @@ abstract class RepositoryClientManager<T, C extends Serializable> implements IRe } + protected void handleError(String message, Throwable e) { + StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN, message, e)); + } + public void writeCache() { if (cacheFile == null) { return; @@ -141,8 +177,7 @@ abstract class RepositoryClientManager<T, C extends Serializable> implements IRe out.writeObject(clientDataByUrl.get(url)); } } catch (IOException e) { - StatusHandler.log(new Status(IStatus.WARNING, ITasksCoreConstants.ID_PLUGIN, - "The respository configuration cache could not be written", e)); //$NON-NLS-1$ + handleError("The respository configuration cache could not be written", e); //$NON-NLS-1$ } finally { if (out != null) { try { diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java index 3ff8eb277..4d50c1a2f 100644 --- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/AllTasksTests.java @@ -18,6 +18,7 @@ import org.eclipse.mylyn.tasks.tests.bugs.SupportHandlerManagerTest; import org.eclipse.mylyn.tasks.tests.core.FileTaskAttachmentSourceTest; import org.eclipse.mylyn.tasks.tests.core.ITasksCoreConstantsTest; import org.eclipse.mylyn.tasks.tests.core.PriorityLevelTest; +import org.eclipse.mylyn.tasks.tests.core.RepositoryClientManagerTest; import org.eclipse.mylyn.tasks.tests.core.TaskListUnmatchedContainerTest; import org.eclipse.mylyn.tasks.tests.core.TaskRepositoryLocationTest; import org.eclipse.mylyn.tasks.tests.core.TaskRepositoryTest; @@ -126,6 +127,7 @@ public class AllTasksTests { suite.addTestSuite(PriorityLevelTest.class); suite.addTestSuite(TaskAttributeMapperTest.class); suite.addTestSuite(SupportHandlerManagerTest.class); + suite.addTestSuite(RepositoryClientManagerTest.class); return suite; } diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/RepositoryClientManagerTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/RepositoryClientManagerTest.java new file mode 100644 index 000000000..8e55500ca --- /dev/null +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/RepositoryClientManagerTest.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2012 Tasktop Technologies and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.tasks.tests.core; + +import java.io.File; +import java.io.Serializable; + +import junit.framework.TestCase; + +import org.eclipse.mylyn.internal.provisional.tasks.core.RepositoryClientManager; +import org.eclipse.mylyn.tasks.core.TaskRepository; + +/** + * @author Benjamin Muskalla + */ +public class RepositoryClientManagerTest extends TestCase { + + private static class MyConfig implements Serializable { + + private static final long serialVersionUID = 5105526708474366441L; + + public String someString = "mylyn"; + + public TaskRepository repository = null; + + } + + private class MockRepositoryClientManager extends RepositoryClientManager<Object, MyConfig> { + + private Throwable throwable; + + public MockRepositoryClientManager(File cacheFile) { + super(cacheFile); + } + + @Override + protected MyConfig createRepositoryConfiguration() { + return new MyConfig(); + } + + @Override + protected Object createClient(TaskRepository taskRepository, MyConfig data) { + return new Object(); + } + + @Override + protected void handleError(String message, Throwable e) { + throwable = e; + } + + public Throwable getThrowable() { + return throwable; + } + + } + + public void testClassloadingSerialize() throws Exception { + File cacheFile = File.createTempFile("config", ""); + cacheFile.delete(); + MockRepositoryClientManager manager = new MockRepositoryClientManager(cacheFile); + TaskRepository repository = new TaskRepository("kind", "url"); + manager.getClient(repository); + manager.writeCache(); + assertNull(manager.getThrowable()); + manager.readCache(); + assertNull(manager.getThrowable()); + } +} |