Skip to content

Commit 91fc5af

Browse files
authored
Fixes #800 - API attacher - Download source artifact and set its location in the classpath entry (#956)
* WIP - Fixes #800 - API attacher - Download source artifact and set its location in the classpath entry * refactor FileDownloader to extract and move to c.g.c.t.e.util bundle * WIP - CP container serialization improvement for source attachment path * fix sourceattachment path when initializing container * review comments addressed, TestHttpServer added to test FileDownloader * minor fix in comment, update required guava version in util bundle * attempt to clarify TODO comment
1 parent 3d42fdb commit 91fc5af

File tree

20 files changed

+581
-64
lines changed

20 files changed

+581
-64
lines changed

plugins/com.google.cloud.tools.eclipse.appengine.libraries.test/src/com/google/cloud/tools/eclipse/appengine/libraries/AppEngineLibraryContainerInitializerTest.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ public class AppEngineLibraryContainerInitializerTest {
6666
@Mock private LibraryFactory libraryFactory;
6767
@Mock private IConfigurationElement configurationElement;
6868
@Mock private LibraryContainerStateLocationProvider containerStateProvider;
69-
@Mock private ArtifactBaseLocationProvider artifactBaseLocationProvider;
69+
@Mock private ArtifactBaseLocationProvider binaryBaseLocationProvider;
70+
@Mock private ArtifactBaseLocationProvider sourceBaseLocationProvider;
7071
@Mock private ILibraryRepositoryService repositoryService;
7172

7273
private LibraryClasspathContainerSerializer serializer;
@@ -202,8 +203,11 @@ private void setupLibraryFactory() throws LibraryFactoryException {
202203
}
203204

204205
private void setupSerializer() throws IOException, CoreException {
205-
serializer = new LibraryClasspathContainerSerializer(containerStateProvider, artifactBaseLocationProvider);
206-
when(artifactBaseLocationProvider.getBaseLocation()).thenReturn(new Path("/test"));
206+
serializer = new LibraryClasspathContainerSerializer(containerStateProvider,
207+
binaryBaseLocationProvider,
208+
sourceBaseLocationProvider);
209+
when(binaryBaseLocationProvider.getBaseLocation()).thenReturn(new Path("/test"));
210+
when(sourceBaseLocationProvider.getBaseLocation()).thenReturn(new Path("/test"));
207211
File stateFile = stateLocationFolder.newFile();
208212
when(containerStateProvider.getContainerStateFile(any(IJavaProject.class),
209213
eq(new Path(TEST_LIBRARY_PATH)),

plugins/com.google.cloud.tools.eclipse.appengine.libraries.test/src/com/google/cloud/tools/eclipse/appengine/libraries/persistence/LibraryClasspathContainerSerializerTest.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public class LibraryClasspathContainerSerializerTest {
6868
+ " \"pattern\": \"/com/example/nonaccessible\""
6969
+ " }"
7070
+ " ],"
71-
+ " \"sourceAttachmentPath\": \"/test/path/to/src\","
71+
+ " \"sourceAttachmentPath\": \"SRC/path/to/src\","
7272
+ " \"path\": \"path/to/jar\","
7373
+ " \"attributes\": ["
7474
+ " {"
@@ -81,7 +81,8 @@ public class LibraryClasspathContainerSerializerTest {
8181
+ "}";
8282

8383
@Mock private LibraryContainerStateLocationProvider stateLocationProvider;
84-
@Mock private ArtifactBaseLocationProvider artifactBaseLocationProvider;
84+
@Mock private ArtifactBaseLocationProvider binaryBaseLocationProvider;
85+
@Mock private ArtifactBaseLocationProvider sourceBaseLocationProvider;
8586
@Mock private IJavaProject javaProject;
8687

8788
@Rule
@@ -102,7 +103,8 @@ public void setUp() throws Exception {
102103
false /* accessible */) },
103104
true)
104105
};
105-
when(artifactBaseLocationProvider.getBaseLocation()).thenReturn(new Path("/test"));
106+
when(binaryBaseLocationProvider.getBaseLocation()).thenReturn(new Path("/test"));
107+
when(sourceBaseLocationProvider.getBaseLocation()).thenReturn(new Path("/test"));
106108
container = new LibraryClasspathContainer(new Path(CONTAINER_PATH),
107109
CONTAINER_DESCRIPTION,
108110
classpathEntries);
@@ -115,7 +117,8 @@ public void testSaveAndLoadContainer() throws CoreException, IOException {
115117
.thenReturn(stateFilePath);
116118
LibraryClasspathContainerSerializer serializer =
117119
new LibraryClasspathContainerSerializer(stateLocationProvider,
118-
artifactBaseLocationProvider);
120+
binaryBaseLocationProvider,
121+
sourceBaseLocationProvider);
119122
serializer.saveContainer(javaProject, container);
120123
LibraryClasspathContainer containerFromFile = serializer.loadContainer(javaProject, new Path(CONTAINER_PATH));
121124
compare(container, containerFromFile);
@@ -131,7 +134,8 @@ public void testLoadContainer() throws IOException, CoreException {
131134
StandardOpenOption.TRUNCATE_EXISTING);
132135
LibraryClasspathContainerSerializer serializer =
133136
new LibraryClasspathContainerSerializer(stateLocationProvider,
134-
artifactBaseLocationProvider);
137+
binaryBaseLocationProvider,
138+
sourceBaseLocationProvider);
135139
LibraryClasspathContainer containerFromFile = serializer.loadContainer(javaProject, new Path(CONTAINER_PATH));
136140
compare(container, containerFromFile);
137141
}
@@ -143,7 +147,8 @@ public void testSaveContainer() throws CoreException, IOException {
143147
.thenReturn(stateFilePath);
144148
LibraryClasspathContainerSerializer serializer =
145149
new LibraryClasspathContainerSerializer(stateLocationProvider,
146-
artifactBaseLocationProvider);
150+
binaryBaseLocationProvider,
151+
sourceBaseLocationProvider);
147152
serializer.saveContainer(javaProject, container);
148153
// use JsonObject.equals()
149154
assertEquals(new JsonParser().parse(SERIALIZED_CONTAINER),
@@ -154,15 +159,17 @@ public void testSaveContainer() throws CoreException, IOException {
154159
public void testSaveContainer_nullStateFileLocationNoError() throws IOException, CoreException {
155160
LibraryClasspathContainerSerializer serializer =
156161
new LibraryClasspathContainerSerializer(stateLocationProvider,
157-
artifactBaseLocationProvider);
162+
binaryBaseLocationProvider,
163+
sourceBaseLocationProvider);
158164
serializer.saveContainer(javaProject, container);
159165
}
160166

161167
@Test
162168
public void testLoadContainer_nullStateFileLocationNoError() throws IOException, CoreException {
163169
LibraryClasspathContainerSerializer serializer =
164170
new LibraryClasspathContainerSerializer(stateLocationProvider,
165-
artifactBaseLocationProvider);
171+
binaryBaseLocationProvider,
172+
sourceBaseLocationProvider);
166173
assertNull(serializer.loadContainer(javaProject, new Path(CONTAINER_PATH)));
167174
}
168175

plugins/com.google.cloud.tools.eclipse.appengine.libraries.test/src/com/google/cloud/tools/eclipse/appengine/libraries/repository/M2RepositoryServiceTest.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.hamcrest.CoreMatchers.is;
2121
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
2222
import static org.hamcrest.collection.IsArrayContaining.hasItemInArray;
23+
import static org.junit.Assert.assertEquals;
2324
import static org.junit.Assert.assertThat;
2425
import static org.mockito.Matchers.any;
2526
import static org.mockito.Matchers.anyListOf;
@@ -37,7 +38,9 @@
3738
import org.eclipse.core.runtime.CoreException;
3839
import org.eclipse.core.runtime.IPath;
3940
import org.eclipse.core.runtime.IProgressMonitor;
41+
import org.eclipse.core.runtime.Path;
4042
import org.eclipse.jdt.core.IClasspathAttribute;
43+
import org.junit.Before;
4144
import org.junit.Test;
4245
import org.junit.runner.RunWith;
4346
import org.mockito.Mock;
@@ -53,10 +56,15 @@ public class M2RepositoryServiceTest {
5356

5457
private M2RepositoryService m2RepositoryService;
5558

59+
@Before
60+
public void setUp() {
61+
m2RepositoryService = new M2RepositoryService();
62+
m2RepositoryService.setMavenHelper(mavenHelper);
63+
m2RepositoryService.setTransformer(transformer);
64+
}
65+
5666
@Test(expected = LibraryRepositoryServiceException.class)
5767
public void getLibraryClasspathEntry_errorInArtifactResolution() throws Exception {
58-
M2RepositoryService m2RepositoryService = new M2RepositoryService();
59-
m2RepositoryService.setMavenHelper(mavenHelper);
6068
when(mavenHelper.resolveArtifact(any(IProgressMonitor.class), any(MavenCoordinates.class),
6169
anyListOf(ArtifactRepository.class)))
6270
.thenThrow(testCoreException());
@@ -67,28 +75,20 @@ public void getLibraryClasspathEntry_errorInArtifactResolution() throws Exceptio
6775

6876
@Test(expected = LibraryRepositoryServiceException.class)
6977
public void getLibraryClasspathEntry_invalidRepositoryId() throws LibraryRepositoryServiceException {
70-
M2RepositoryService m2RepositoryService = new M2RepositoryService();
71-
m2RepositoryService.setMavenHelper(mavenHelper);
72-
7378
MavenCoordinates mavenCoordinates = new MavenCoordinates("groupId", "artifactId");
7479
mavenCoordinates.setRepository("invalid_repository_id");
7580
m2RepositoryService.getLibraryClasspathEntry(new LibraryFile(mavenCoordinates));
7681
}
7782

7883
@Test(expected = LibraryRepositoryServiceException.class)
7984
public void getLibraryClasspathEntry_invalidRepositoryURI() throws LibraryRepositoryServiceException {
80-
M2RepositoryService m2RepositoryService = new M2RepositoryService();
81-
m2RepositoryService.setMavenHelper(mavenHelper);
82-
8385
MavenCoordinates mavenCoordinates = new MavenCoordinates("groupId", "artifactId");
8486
mavenCoordinates.setRepository("http://");
8587
m2RepositoryService.getLibraryClasspathEntry(new LibraryFile(mavenCoordinates));
8688
}
8789

8890
@Test(expected = LibraryRepositoryServiceException.class)
8991
public void getLibraryClasspathEntry_customRepositoryCreationError() throws Exception {
90-
M2RepositoryService m2RepositoryService = new M2RepositoryService();
91-
m2RepositoryService.setMavenHelper(mavenHelper);
9292
when(mavenHelper.createArtifactRepository("example.com", "http://example.com")).thenThrow(testCoreException());
9393

9494
MavenCoordinates mavenCoordinates = new MavenCoordinates("groupId", "artifactId");
@@ -98,9 +98,6 @@ public void getLibraryClasspathEntry_customRepositoryCreationError() throws Exce
9898

9999
@Test
100100
public void getLibraryClasspathEntry_customRepositoryURI() throws Exception {
101-
M2RepositoryService m2RepositoryService = new M2RepositoryService();
102-
m2RepositoryService.setMavenHelper(mavenHelper);
103-
m2RepositoryService.setTransformer(transformer);
104101
when(mavenHelper.createArtifactRepository("example.com", "http://example.com"))
105102
.thenReturn(mock(ArtifactRepository.class));
106103
Artifact artifact = getMockArtifactWithJarPath();
@@ -116,9 +113,6 @@ public void getLibraryClasspathEntry_customRepositoryURI() throws Exception {
116113

117114
@Test
118115
public void getLibraryClasspathEntry_withJavadoc() throws Exception {
119-
M2RepositoryService m2RepositoryService = new M2RepositoryService();
120-
m2RepositoryService.setMavenHelper(mavenHelper);
121-
m2RepositoryService.setTransformer(transformer);
122116
Artifact artifact = getMockArtifactWithJarPath();
123117
when(mavenHelper.resolveArtifact(any(IProgressMonitor.class),
124118
any(MavenCoordinates.class),
@@ -134,6 +128,19 @@ public void getLibraryClasspathEntry_withJavadoc() throws Exception {
134128
is("http://example.com/javadoc")))));
135129
}
136130

131+
@Test
132+
public void getLibraryClasspathEntry_withInvalidSourceUriMavenSourceResolutionHappens() throws Exception {
133+
Artifact artifact = getMockArtifactWithJarPath();
134+
when(mavenHelper.resolveArtifact(any(IProgressMonitor.class),
135+
any(MavenCoordinates.class),
136+
anyListOf(ArtifactRepository.class))).thenReturn(artifact);
137+
MavenCoordinates mavenCoordinates = new MavenCoordinates("groupId", "artifactId");
138+
LibraryFile libraryFile = new LibraryFile(mavenCoordinates);
139+
libraryFile.setSourceUri(new URI("foo/bar"));
140+
IPath sourcePath = m2RepositoryService.getLibraryClasspathEntry(libraryFile).getSourceAttachmentPath();
141+
assertEquals(new Path(FAKE_PATH), sourcePath);
142+
}
143+
137144
@Test(expected = IllegalStateException.class)
138145
public void testMavenHelperMustBeSet() throws LibraryRepositoryServiceException {
139146
new M2RepositoryService().getLibraryClasspathEntry(new LibraryFile(new MavenCoordinates("groupId", "artifactId")));

plugins/com.google.cloud.tools.eclipse.appengine.libraries/META-INF/MANIFEST.MF

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ Import-Package: com.google.cloud.tools.eclipse.util,
1818
com.google.cloud.tools.eclipse.util.io,
1919
com.google.cloud.tools.eclipse.util.service,
2020
com.google.cloud.tools.eclipse.util.status,
21-
com.google.common.annotations;version="15.0.0",
22-
com.google.common.base,
23-
com.google.common.collect;version="15.0.0",
21+
com.google.common.annotations;version="17.0.0",
22+
com.google.common.base;version="17.0.0",
23+
com.google.common.collect;version="17.0.0",
2424
com.google.gson;version="2.7",
2525
org.eclipse.core.resources,
2626
org.eclipse.core.runtime;version="3.5.0",

plugins/com.google.cloud.tools.eclipse.appengine.libraries/src/com/google/cloud/tools/eclipse/appengine/libraries/AppEngineLibraryContainerInitializer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ private void validateJarPaths(LibraryClasspathContainer container) throws Librar
121121
IClasspathEntry[] classpathEntries = container.getClasspathEntries();
122122
for (int i = 0; i < classpathEntries.length; i++) {
123123
IClasspathEntry classpathEntry = classpathEntries[i];
124-
if (!classpathEntry.getPath().toFile().exists()) {
124+
if (!classpathEntry.getPath().toFile().exists()
125+
|| (classpathEntry.getSourceAttachmentPath() != null
126+
&& !classpathEntry.getSourceAttachmentPath().toFile().exists())) {
125127
classpathEntries[i] = repositoryService.rebuildClasspathEntry(classpathEntry);
126128
}
127129
}

plugins/com.google.cloud.tools.eclipse.appengine.libraries/src/com/google/cloud/tools/eclipse/appengine/libraries/model/MavenCoordinates.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.google.cloud.tools.eclipse.appengine.libraries.model;
1818

1919
import com.google.common.base.Preconditions;
20+
import java.text.MessageFormat;
2021

2122
/**
2223
* Describes a Maven artifact.
@@ -50,6 +51,18 @@ public MavenCoordinates(String groupId, String artifactId) {
5051
this.artifactId = artifactId;
5152
}
5253

54+
/**
55+
* Copy constructor
56+
*/
57+
public MavenCoordinates(MavenCoordinates mavenCoordinates) {
58+
repository = mavenCoordinates.repository;
59+
groupId = mavenCoordinates.groupId;
60+
artifactId = mavenCoordinates.artifactId;
61+
version = mavenCoordinates.version;
62+
type = mavenCoordinates.type;
63+
classifier = mavenCoordinates.classifier;
64+
}
65+
5366
/**
5467
* @return the Maven version of the artifact, defaults to special value {@link MavenCoordinates#LATEST_VERSION}, never
5568
* <code>null</code>
@@ -129,4 +142,10 @@ public String getGroupId() {
129142
public String getArtifactId() {
130143
return artifactId;
131144
}
145+
146+
@Override
147+
public String toString() {
148+
return MessageFormat.format("MavenCoordinates [repository={0}, {1}:{2}:{3}:{4}:{5}]",
149+
repository, groupId, artifactId, type, classifier, version);
150+
}
132151
}

plugins/com.google.cloud.tools.eclipse.appengine.libraries/src/com/google/cloud/tools/eclipse/appengine/libraries/persistence/LibraryClasspathContainerSerializer.java

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.cloud.tools.eclipse.appengine.libraries.LibraryClasspathContainer;
2020
import com.google.common.annotations.VisibleForTesting;
2121
import com.google.common.base.Charsets;
22+
import com.google.common.base.Preconditions;
2223
import com.google.gson.Gson;
2324
import com.google.gson.GsonBuilder;
2425
import java.io.ByteArrayInputStream;
@@ -33,9 +34,11 @@
3334
import org.eclipse.core.runtime.CoreException;
3435
import org.eclipse.core.runtime.IPath;
3536
import org.eclipse.core.runtime.Path;
37+
import org.eclipse.core.runtime.Platform;
3638
import org.eclipse.e4.core.di.annotations.Creatable;
3739
import org.eclipse.jdt.core.IJavaProject;
3840
import org.eclipse.m2e.core.MavenPlugin;
41+
import org.osgi.framework.Bundle;
3942
import org.osgi.framework.FrameworkUtil;
4043

4144
/**
@@ -71,17 +74,22 @@ public interface ArtifactBaseLocationProvider {
7174
}
7275

7376
private LibraryContainerStateLocationProvider stateLocationProvider;
74-
private ArtifactBaseLocationProvider artifactBaseLocationProvider;
77+
private ArtifactBaseLocationProvider binaryArtifactBaseLocationProvider;
78+
private ArtifactBaseLocationProvider sourceBaseLocationProvider;
7579

7680
public LibraryClasspathContainerSerializer() {
77-
this(new DefaultStateLocationProvider(), new M2LocalRepositoryLocationProvider());
81+
this(new DefaultStateLocationProvider(),
82+
new M2LocalRepositoryLocationProvider(),
83+
new LibrariesBundleStateLocationProvider());
7884
}
7985

8086
@VisibleForTesting
8187
public LibraryClasspathContainerSerializer(LibraryContainerStateLocationProvider stateLocationProvider,
82-
ArtifactBaseLocationProvider artifactBaseLocationProvider) {
88+
ArtifactBaseLocationProvider binaryBaseLocationProvider,
89+
ArtifactBaseLocationProvider sourceBaseLocationProvider) {
8390
this.stateLocationProvider = stateLocationProvider;
84-
this.artifactBaseLocationProvider = artifactBaseLocationProvider;
91+
this.binaryArtifactBaseLocationProvider = binaryBaseLocationProvider;
92+
this.sourceBaseLocationProvider = sourceBaseLocationProvider;
8593
}
8694

8795
public void saveContainer(IJavaProject javaProject, LibraryClasspathContainer container) throws IOException,
@@ -94,7 +102,8 @@ public void saveContainer(IJavaProject javaProject, LibraryClasspathContainer co
94102
try (OutputStreamWriter outputStream = new OutputStreamWriter(new FileOutputStream(stateFile), Charsets.UTF_8)) {
95103
Gson gson = new GsonBuilder().setPrettyPrinting().create();
96104
outputStream.write(gson.toJson(new SerializableLibraryClasspathContainer(container,
97-
artifactBaseLocationProvider.getBaseLocation())));
105+
binaryArtifactBaseLocationProvider.getBaseLocation(),
106+
sourceBaseLocationProvider.getBaseLocation())));
98107
}
99108
}
100109

@@ -108,7 +117,8 @@ public LibraryClasspathContainer loadContainer(IJavaProject javaProject, IPath c
108117
Gson gson = new GsonBuilder().create();
109118
SerializableLibraryClasspathContainer fromJson =
110119
gson.fromJson(fileReader, SerializableLibraryClasspathContainer.class);
111-
return fromJson.toLibraryClasspathContainer(artifactBaseLocationProvider.getBaseLocation());
120+
return fromJson.toLibraryClasspathContainer(binaryArtifactBaseLocationProvider.getBaseLocation(),
121+
sourceBaseLocationProvider.getBaseLocation());
112122
}
113123
}
114124

@@ -154,4 +164,20 @@ public IPath getBaseLocation() {
154164
return new Path(MavenPlugin.getRepositoryRegistry().getLocalRepository().getBasedir().getAbsolutePath());
155165
}
156166
}
167+
168+
private static class LibrariesBundleStateLocationProvider implements ArtifactBaseLocationProvider {
169+
170+
private static final String APPENGINE_LIBRARIES_BUNDLE_NAME = "com.google.cloud.tools.eclipse.appengine.libraries";
171+
172+
/**
173+
* @see com.google.cloud.tools.eclipse.appengine.libraries.persistence.LibraryClasspathContainerSerializer.ArtifactBaseLocationProvider#getBaseLocation()
174+
*/
175+
@Override
176+
public IPath getBaseLocation() {
177+
Bundle librariesBundle = Platform.getBundle(APPENGINE_LIBRARIES_BUNDLE_NAME);
178+
Preconditions.checkState(librariesBundle != null,
179+
"Bundle Cloud Tools For Eclipse App Engine Libraries Management not found");
180+
return Platform.getStateLocation(librariesBundle);
181+
}
182+
}
157183
}

0 commit comments

Comments
 (0)