diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java index 8b93138d0d22..e57bf843a7ac 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/FacetLibrariesValidatorImpl.java @@ -87,14 +87,13 @@ public class FacetLibrariesValidatorImpl extends FacetLibrariesValidator { } String missingJars = IdeBundle.message("label.missed.libraries.prefix") + " " + info.getMissingJarsText(); - final String text = IdeBundle.message("label.missed.libraries.text", missingJars, info.getClassNames()[0]); LibraryInfo[] missingLibraries = info.getLibraryInfos(); VirtualFile baseDir = myContext.getModule().getProject().getBaseDir(); final String baseDirPath = baseDir != null ? baseDir.getPath() : ""; LibraryCompositionSettings libraryCompositionSettings = new LibraryCompositionSettings(missingLibraries, myDescription.getDefaultLibraryName(), baseDirPath, myDescription.getDefaultLibraryName(), null); - return new ValidationResult(text, new LibrariesQuickFix(libraryCompositionSettings)); + return new ValidationResult(missingJars, new LibrariesQuickFix(libraryCompositionSettings)); } private void onChange() { diff --git a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/RequiredLibrariesInfo.java b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/RequiredLibrariesInfo.java index b2452b050fe1..c2d7da4e60bd 100644 --- a/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/RequiredLibrariesInfo.java +++ b/java/idea-ui/src/com/intellij/facet/impl/ui/libraries/RequiredLibrariesInfo.java @@ -16,12 +16,19 @@ package com.intellij.facet.impl.ui.libraries; +import com.intellij.facet.frameworks.ExistedJarDiscover; +import com.intellij.facet.frameworks.LibrariesDownloadAssistant; import com.intellij.facet.ui.libraries.LibraryInfo; import com.intellij.openapi.roots.libraries.LibraryUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; +import org.apache.commons.codec.binary.Hex; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.security.MessageDigest; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -33,7 +40,8 @@ public class RequiredLibrariesInfo { private final List myLibraryInfos = new ArrayList(); - public RequiredLibrariesInfo() {} + public RequiredLibrariesInfo() { + } public RequiredLibrariesInfo(LibraryInfo... libs) { myLibraryInfos.addAll(new ArrayList(Arrays.asList(libs))); @@ -43,16 +51,29 @@ public class RequiredLibrariesInfo { myLibraryInfos.add(lib); } - public @Nullable RequiredClassesNotFoundInfo checkLibraries(VirtualFile[] libraryFiles, boolean all) { + public + @Nullable + RequiredClassesNotFoundInfo checkLibraries(VirtualFile[] libraryFiles, boolean all) { List infos = new ArrayList(); List classes = new ArrayList(); for (LibraryInfo info : myLibraryInfos) { - boolean notFound = all && info.getRequiredClasses().length == 0; - for (String className : info.getRequiredClasses()) { - if (!LibraryUtil.isClassAvailableInLibrary(libraryFiles, className)) { - classes.add(className); - notFound = true; + boolean notFound = true; + final String md5 = info.getMd5(); + if (!StringUtil.isEmptyOrSpaces(md5)) { + for (VirtualFile libraryFile : libraryFiles) { + final VirtualFile jarFile = JarFileSystem.getInstance().getVirtualFileForJar(libraryFile); + if (md5.equals(md5(jarFile))) { + notFound = false; + break; + } + } + } else { + for (String className : info.getRequiredClasses()) { + if (!LibraryUtil.isClassAvailableInLibrary(libraryFiles, className)) { + classes.add(className); + notFound = true; + } } } @@ -66,6 +87,20 @@ public class RequiredLibrariesInfo { return new RequiredClassesNotFoundInfo(ArrayUtil.toStringArray(classes), infos.toArray(new LibraryInfo[infos.size()])); } + @Nullable + public static String md5(@NotNull VirtualFile file) { + try { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update(file.contentsToByteArray()); + final byte[] digest = md5.digest(); + + return new String(Hex.encodeHex(digest)); + } + catch (Exception e) { + return null; + } + } + public static String getLibrariesPresentableText(final LibraryInfo[] libraryInfos) { StringBuilder missedJarsText = new StringBuilder(); for (int i = 0; i < libraryInfos.length; i++) { @@ -98,6 +133,5 @@ public class RequiredLibrariesInfo { public String getMissingJarsText() { return getLibrariesPresentableText(myLibraryInfos); } - } } diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java index 185a37d799fd..3146324b21e4 100644 --- a/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java +++ b/platform/lang-api/src/com/intellij/facet/frameworks/LibrariesDownloadAssistant.java @@ -1,21 +1,33 @@ package com.intellij.facet.frameworks; +import com.intellij.facet.frameworks.actions.GetAllVersionsAction; +import com.intellij.facet.frameworks.actions.GetVersionInfoAction; import com.intellij.facet.frameworks.beans.DownloadJar; import com.intellij.facet.frameworks.beans.Version; import com.intellij.facet.frameworks.beans.Versions; import com.intellij.facet.ui.libraries.LibraryInfo; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import com.intellij.util.xmlb.XmlSerializer; +import org.apache.commons.codec.binary.Hex; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; import java.net.URL; +import java.net.URLConnection; +import java.security.MessageDigest; import java.util.Arrays; import java.util.List; +import java.util.Properties; import java.util.Set; public class LibrariesDownloadAssistant { @@ -40,19 +52,32 @@ public class LibrariesDownloadAssistant { return versions.toArray(new Version[versions.size()]); } - // todo: will be connect to server @Nullable - public static Version[] getVersions(@NotNull String groupId) { - final Versions allVersions = - XmlSerializer.deserialize(getRoot(groupId), Versions.class); + public static Version[] getVersions(@NotNull String id) { + final URL url = GetAllVersionsAction.create(id).getUrl(); + + if (url == null) return null; + + final Versions allVersions = XmlSerializer.deserialize(url, Versions.class); return allVersions == null ? null : allVersions.getVersions(); } - private static Element getRoot(@NotNull final String groupId) { - return null; - } + @Nullable + public static Version getVersion(@NotNull String id, @NotNull String versionId) { + final URL url = GetVersionInfoAction.create(id, versionId).getUrl(); + if (url == null) return null; + final Versions allVersions = XmlSerializer.deserialize(url, Versions.class); + + if(allVersions == null) return null; + + final Version[] versions = allVersions.getVersions(); + + assert versions.length == 1; + + return versions[0]; + } @Nullable public static Version findVersion(@NotNull final String versionId, @NotNull final URL... urls) { @@ -76,21 +101,26 @@ public class LibrariesDownloadAssistant { @NotNull public static LibraryInfo[] getLibraryInfos(@NotNull final URL url, @NotNull final String versionId) { final Version version = findVersion(getVersions(url), versionId); - return version != null ? getLibraryInfos(version) :LibraryInfo.EMPTY_ARRAY; + return version != null ? getLibraryInfos(version) : LibraryInfo.EMPTY_ARRAY; } - + @NotNull public static LibraryInfo[] getLibraryInfos(@Nullable Version version) { if (version == null) return LibraryInfo.EMPTY_ARRAY; - final List infos = ContainerUtil.mapNotNull(version.getJars(), new Function() { - @Override - public LibraryInfo fun(DownloadJar downloadJar) { - final String downloadUrl = downloadJar.getDownloadUrl(); - return new LibraryInfo(downloadJar.getName(), downloadUrl, downloadUrl, downloadJar.getRequiredClasses()); - } - }); + final List infos = convert(version.getJars()); return infos.toArray(new LibraryInfo[infos.size()]); } + + @NotNull + public static List convert(@NotNull DownloadJar[] jars) { + return ContainerUtil.mapNotNull(jars, new Function() { + @Override + public LibraryInfo fun(DownloadJar downloadJar) { + final String downloadUrl = downloadJar.getDownloadUrl(); + return new LibraryInfo(downloadJar.getName(), downloadUrl, downloadUrl, downloadJar.getMD5(), downloadJar.getRequiredClasses()); + } + }); + } } diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/actions/AbstractAction.java b/platform/lang-api/src/com/intellij/facet/frameworks/actions/AbstractAction.java new file mode 100644 index 000000000000..cac0f9c0aac2 --- /dev/null +++ b/platform/lang-api/src/com/intellij/facet/frameworks/actions/AbstractAction.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.facet.frameworks.actions; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.registry.Registry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.net.MalformedURLException; +import java.net.URL; + +public abstract class AbstractAction { + private static final Logger LOG = Logger.getInstance(AbstractAction.class.getName()); + + private static String SERVER_URL = Registry.get("frameworks.download.libraries.server.url").asString(); + private Pair[] myParams; + + protected AbstractAction(Pair... params) { + myParams = params; + } + + @NotNull + public abstract String getActionName(); + + @Nullable + public URL getUrl() { + final String parameters = getParametersAsString(); + + try { + return new URL(SERVER_URL + "/" + getActionName() + (parameters.length() == 0 ? "" : "?" + parameters)); + } + catch (MalformedURLException e) { + LOG.error(e); + } + + return null; + } + + @NotNull + private String getParametersAsString() { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < myParams.length; i++) { + Pair param = myParams[i]; + if (i > 0) buffer.append("&"); + buffer.append(param.first); + buffer.append("="); + buffer.append(param.second); + } + + return buffer.toString(); + } +} diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/actions/GetAllVersionsAction.java b/platform/lang-api/src/com/intellij/facet/frameworks/actions/GetAllVersionsAction.java new file mode 100644 index 000000000000..9b8bd349b6f0 --- /dev/null +++ b/platform/lang-api/src/com/intellij/facet/frameworks/actions/GetAllVersionsAction.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.facet.frameworks.actions; + +import com.intellij.openapi.util.Pair; +import org.jetbrains.annotations.NotNull; + +public class GetAllVersionsAction extends AbstractAction { + private GetAllVersionsAction(@NotNull String id) { + super(Pair.create("id", id)); + } + + public static GetAllVersionsAction create(@NotNull String id) { + return new GetAllVersionsAction(id); + } + + @NotNull + @Override + public String getActionName() { + return "ListVersions.action"; + } +} diff --git a/platform/lang-api/src/com/intellij/facet/frameworks/actions/GetVersionInfoAction.java b/platform/lang-api/src/com/intellij/facet/frameworks/actions/GetVersionInfoAction.java new file mode 100644 index 000000000000..c2ed867d2a5d --- /dev/null +++ b/platform/lang-api/src/com/intellij/facet/frameworks/actions/GetVersionInfoAction.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.facet.frameworks.actions; + +import com.intellij.openapi.util.Pair; +import org.jetbrains.annotations.NotNull; + +public class GetVersionInfoAction extends AbstractAction { + private GetVersionInfoAction(@NotNull String id, @NotNull String version) { + super(Pair.create("id", id), Pair.create("version", version)); + } + + public static GetVersionInfoAction create(@NotNull String id, @NotNull String version) { + return new GetVersionInfoAction(id, version); + } + + @NotNull + @Override + public String getActionName() { + return "GetInfo.action"; + } +} diff --git a/platform/lang-api/src/com/intellij/facet/ui/libraries/LibraryInfo.java b/platform/lang-api/src/com/intellij/facet/ui/libraries/LibraryInfo.java index a123c248258c..63700f2ee7a3 100644 --- a/platform/lang-api/src/com/intellij/facet/ui/libraries/LibraryInfo.java +++ b/platform/lang-api/src/com/intellij/facet/ui/libraries/LibraryInfo.java @@ -29,13 +29,15 @@ public class LibraryInfo { private @Nullable final LibraryDownloadInfo myDownloadInfo; private @NonNls final String myName; + @Nullable private String myMd5; private @NonNls final String[] myRequiredClasses; private boolean mySelected = true; public LibraryInfo(final @NonNls String name, final @Nullable @NonNls String downloadingUrl, - final @Nullable String presentableUrl, final @NonNls String... requiredClasses) { + final @Nullable String presentableUrl, final @Nullable String md5, final @NonNls String... requiredClasses) { myName = name; + myMd5 = md5; myRequiredClasses = requiredClasses; if (downloadingUrl != null) { int dot = name.lastIndexOf('.'); @@ -102,4 +104,9 @@ public class LibraryInfo { public void setSelected(boolean selected) { mySelected = selected; } + + @Nullable + public String getMd5() { + return myMd5; + } } diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 8efba5ea58be..db143a07f57b 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -98,3 +98,4 @@ structureView.coalesceTime=500 jar.build=false keymap.show.alias.actions=false +frameworks.download.libraries.server.url=http://pluginsrepo-test:8080 \ No newline at end of file