diff --git a/.idea/modules.xml b/.idea/modules.xml index 8f16bb372d09..c9b64c74cd29 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -121,6 +121,8 @@ + + diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index 728ab72cb1ae..98e90daab219 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -56,6 +56,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir "testFramework-java", "debugger-openapi", "compiler-openapi", + "remote-servers-api", "dom-openapi", "execution-openapi", "jsp-openapi", @@ -64,6 +65,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir //noinspection GroovyAssignabilityCheck List implementationModules = [platformImplementationModules, "compiler-impl", + "remote-servers-impl", "debugger-impl", "dom-impl", "execution-impl", diff --git a/community-main.iml b/community-main.iml index b13192ffdbc8..eb59ed11d921 100644 --- a/community-main.iml +++ b/community-main.iml @@ -89,6 +89,7 @@ + diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java index ad0e0d5b353c..354e8533c298 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDClassComment.java @@ -15,9 +15,11 @@ */ package com.intellij.psi.impl.source.codeStyle.javadoc; -import org.jetbrains.annotations.NonNls; +import com.intellij.util.containers.ContainerUtilRt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; +import java.util.List; /** * Class comment @@ -25,51 +27,45 @@ import java.util.ArrayList; * @author Dmitry Skavish */ public class JDClassComment extends JDParamListOwnerComment { - public JDClassComment(CommentFormatter formatter) { + private List myAuthorsList; + private String myVersion; + + public JDClassComment(@NotNull CommentFormatter formatter) { super(formatter); } - private ArrayList authorsList; - private String version; - @Override - protected void generateSpecial(String prefix, @NonNls StringBuffer sb) { + protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) { super.generateSpecial(prefix, sb); - if (!isNull(authorsList)) { - for (Object aAuthorsList : authorsList) { - String s = (String)aAuthorsList; + if (!isNull(myAuthorsList)) { + JDTag tag = JDTag.AUTHOR; + for (String author : myAuthorsList) { sb.append(prefix); - sb.append("@author "); - sb.append(myFormatter.getParser().splitIntoCLines(s, prefix + " ", false)); + sb.append(tag.getWithEndWhitespace()); + sb.append(myFormatter.getParser().formatJDTagDescription(author, tag.getDescriptionPrefix(prefix))); } } - if (!isNull(version)) { + if (!isNull(myVersion)) { sb.append(prefix); - sb.append("@version "); - sb.append(myFormatter.getParser().splitIntoCLines(version, prefix + " ", false)); + JDTag tag = JDTag.VERSION; + sb.append(tag.getWithEndWhitespace()); + sb.append(myFormatter.getParser().formatJDTagDescription(myVersion, tag.getDescriptionPrefix(prefix))); } } - public void addAuthor(String author) { - if (authorsList == null) { - authorsList = new ArrayList(); + public void addAuthor(@NotNull String author) { + if (myAuthorsList == null) { + myAuthorsList = ContainerUtilRt.newArrayList(); } - authorsList.add(author); - } - - public ArrayList getAuthorsList() { - return authorsList; - } - - public void setAuthorsList(ArrayList authorsList) { - this.authorsList = authorsList; + myAuthorsList.add(author); } + @Nullable public String getVersion() { - return version; + return myVersion; } - public void setVersion(String version) { - this.version = version; + public void setVersion(@NotNull String version) { + this.myVersion = version; } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java index cedc9647c49e..28dc6a359942 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java @@ -15,9 +15,11 @@ */ package com.intellij.psi.impl.source.codeStyle.javadoc; -import org.jetbrains.annotations.NonNls; +import com.intellij.util.containers.ContainerUtilRt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; +import java.util.List; /** * @author max @@ -27,43 +29,42 @@ import java.util.ArrayList; * @author Dmitry Skavish */ public class JDComment { - protected CommentFormatter myFormatter; + protected final CommentFormatter myFormatter; - String description; - protected ArrayList unknownList; - protected ArrayList seeAlsoList; - protected String since; - String deprecated; + private String myDescription; + private List myUnknownList; + private List mySeeAlsoList; + private String mySince; + private String myDeprecated; - //protected LinkedHashMap xdocTagMap = new LinkedHashMap(); - - public JDComment(CommentFormatter formatter) { + public JDComment(@NotNull CommentFormatter formatter) { myFormatter = formatter; } - protected static boolean isNull(String s) { + protected static boolean isNull(@Nullable String s) { return s == null || s.trim().length() == 0; } - protected static boolean isNull(ArrayList l) { + protected static boolean isNull(@Nullable List l) { return l == null || l.size() == 0; } - public String generate(String indent) { + @Nullable + public String generate(@NotNull String indent) { final String prefix; + if (myFormatter.getSettings().JD_LEADING_ASTERISKS_ARE_ENABLED) { prefix = indent + " * "; } else { prefix = indent; } - @NonNls StringBuffer sb = new StringBuffer(); -// sb.append("/**\n"); - + StringBuilder sb = new StringBuilder(); int start = sb.length(); - if (!isNull(description)) { - sb.append(myFormatter.getParser().splitIntoCLines(description, prefix)); + if (!isNull(myDescription)) { + sb.append(prefix); + sb.append(myFormatter.getParser().formatJDTagDescription(myDescription, prefix)); if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_DESCRIPTION) { sb.append(prefix); @@ -73,48 +74,40 @@ public class JDComment { generateSpecial(prefix, sb); - if (!isNull(unknownList) && myFormatter.getSettings().JD_KEEP_INVALID_TAGS) { - for (Object aUnknownList : unknownList) { - String s = (String)aUnknownList; - sb.append(myFormatter.getParser().splitIntoCLines(s, prefix)); - } - } - - /* - if( xdocTagMap.size() > 0 ) { - Iterator it = xdocTagMap.values().iterator(); - while( it.hasNext() ) { - ArrayList list = (ArrayList) it.next(); - for( int i = 0; i myThrowsList; - private static final @NonNls String THROWS_TAG = "@throws "; - private static final @NonNls String EXCEPTION_TAG = "@exception "; - - private String returnTag; - private ArrayList throwsList; - - public JDMethodComment(CommentFormatter formatter) { + public JDMethodComment(@NotNull CommentFormatter formatter) { super(formatter); } @Override - protected void generateSpecial(String prefix, @NonNls StringBuffer sb) { + protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) { super.generateSpecial(prefix, sb); - if (returnTag != null) { - if (returnTag.trim().length() != 0 || myFormatter.getSettings().JD_KEEP_EMPTY_RETURN) { + if (myReturnTag != null) { + if (myFormatter.getSettings().JD_KEEP_EMPTY_RETURN || myReturnTag.trim().length() != 0) { + JDTag tag = JDTag.RETURN; sb.append(prefix); - sb.append("@return "); - sb.append(myFormatter.getParser().splitIntoCLines(returnTag, prefix + " ", false)); + sb.append(tag.getWithEndWhitespace()); + sb.append(myFormatter.getParser().formatJDTagDescription(myReturnTag, prefix, true, tag.getDescriptionPrefix(prefix).length())); if (myFormatter.getSettings().JD_ADD_BLANK_AFTER_RETURN) { sb.append(prefix); sb.append('\n'); @@ -52,9 +51,9 @@ public class JDMethodComment extends JDParamListOwnerComment { } } - if (throwsList != null) { - String tag = myFormatter.getSettings().JD_USE_THROWS_NOT_EXCEPTION ? THROWS_TAG : EXCEPTION_TAG; - generateList(prefix, sb, throwsList, tag, + if (myThrowsList != null) { + JDTag tag = myFormatter.getSettings().JD_USE_THROWS_NOT_EXCEPTION ? JDTag.THROWS : JDTag.EXCEPTION; + generateList(prefix, sb, myThrowsList, tag.getWithEndWhitespace(), myFormatter.getSettings().JD_ALIGN_EXCEPTION_COMMENTS, myFormatter.getSettings().JD_KEEP_EMPTY_EXCEPTION, myFormatter.getSettings().JD_PARAM_DESCRIPTION_ON_NEW_LINE @@ -62,19 +61,14 @@ public class JDMethodComment extends JDParamListOwnerComment { } } - public void setReturnTag(String returnTag) { - this.returnTag = returnTag; + public void setReturnTag(@NotNull String returnTag) { + this.myReturnTag = returnTag; } - public ArrayList getThrowsList() { - return throwsList; - } - - public void addThrow(String className, String description) { - if (throwsList == null) { - throwsList = new ArrayList(); + public void addThrow(@NotNull String className, @Nullable String description) { + if (myThrowsList == null) { + myThrowsList = ContainerUtilRt.newArrayList(); } - throwsList.add(new NameDesc(className, description)); + myThrowsList.add(new NameDesc(className, description)); } - } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java index a063cf2935eb..c004bc9adbb1 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParamListOwnerComment.java @@ -25,23 +25,24 @@ import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import org.jetbrains.annotations.NonNls; +import com.intellij.util.containers.ContainerUtilRt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; +import java.util.List; -public class JDParamListOwnerComment extends JDComment{ - protected ArrayList parmsList; - private static final @NonNls String PARAM_TAG = "@param "; +public class JDParamListOwnerComment extends JDComment { + protected List myParamsList; - public JDParamListOwnerComment(CommentFormatter formatter) { + public JDParamListOwnerComment(@NotNull CommentFormatter formatter) { super(formatter); } @Override - protected void generateSpecial(String prefix, StringBuffer sb) { - if (parmsList != null) { + protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) { + if (myParamsList != null) { int before = sb.length(); - generateList(prefix, sb, parmsList, PARAM_TAG, + generateList(prefix, sb, myParamsList, JDTag.PARAM.getWithEndWhitespace(), myFormatter.getSettings().JD_ALIGN_PARAM_COMMENTS, myFormatter.getSettings().JD_KEEP_EMPTY_PARAMETER, myFormatter.getSettings().JD_PARAM_DESCRIPTION_ON_NEW_LINE @@ -55,22 +56,25 @@ public class JDParamListOwnerComment extends JDComment{ } } - public NameDesc getParameter(String name) { - return getNameDesc(name, parmsList); + @Nullable + public NameDesc getParameter(@Nullable String name) { + return getNameDesc(name, myParamsList); } - public void addParameter(String name, String description) { - if (parmsList == null) { - parmsList = new ArrayList(); + public void addParameter(@NotNull String name, @Nullable String description) { + if (myParamsList == null) { + myParamsList = ContainerUtilRt.newArrayList(); } - parmsList.add(new NameDesc(name, description)); + myParamsList.add(new NameDesc(name, description)); } - static NameDesc getNameDesc(String name, ArrayList list) { + @Nullable + private static NameDesc getNameDesc(@Nullable String name, @Nullable List list) { if (list == null) return null; - for (Object aList : list) { - NameDesc parameter = (NameDesc)aList; - if (parameter.name.equals(name)) return parameter; + for (NameDesc aList : list) { + if (aList.name.equals(name)) { + return aList; + } } return null; } @@ -79,10 +83,10 @@ public class JDParamListOwnerComment extends JDComment{ * Generates parameters or exceptions * */ - protected void generateList(String prefix, - StringBuffer sb, - ArrayList list, - String tag, + protected void generateList(@NotNull String prefix, + @NotNull StringBuilder sb, + @NotNull List list, + @NotNull String tag, boolean align_comments, boolean generate_empty_tags, boolean wrapDescription) @@ -104,7 +108,7 @@ public class JDParamListOwnerComment extends JDComment{ } } - StringBuffer fill = new StringBuffer(prefix.length() + tag.length() + max + 1); + StringBuilder fill = new StringBuilder(prefix.length() + tag.length() + max + 1); fill.append(prefix); StringUtil.repeatSymbol(fill, ' ', max + 1 + tag.length()); @@ -113,7 +117,8 @@ public class JDParamListOwnerComment extends JDComment{ if (isNull(nd.desc) && !generate_empty_tags) continue; if (wrapDescription && !isNull(nd.desc)) { sb.append(prefix).append(tag).append(nd.name).append("\n"); - sb.append(myFormatter.getParser().splitIntoCLines(nd.desc, wrapParametersPrefix)); + sb.append(wrapParametersPrefix); + sb.append(myFormatter.getParser().formatJDTagDescription(nd.desc, wrapParametersPrefix)); } else if (align_comments) { sb.append(prefix); @@ -121,11 +126,13 @@ public class JDParamListOwnerComment extends JDComment{ sb.append(nd.name); int spacesNumber = max + 1 - nd.name.length(); StringUtil.repeatSymbol(sb, ' ', Math.max(0, spacesNumber)); - sb.append(myFormatter.getParser().splitIntoCLines(nd.desc, fill, false)); + sb.append(myFormatter.getParser().formatJDTagDescription(nd.desc, fill)); } else { - sb.append(myFormatter.getParser().splitIntoCLines(tag + nd.name + " " + nd.desc, prefix, true)); + sb.append(prefix); + String description = (nd.desc == null) ? "" : nd.desc; + sb.append(myFormatter.getParser().formatJDTagDescription(tag + nd.name + " " + description, prefix)); } } } -} \ No newline at end of file +} diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java index 1f7d047acc7a..859e848d3304 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java @@ -16,8 +16,9 @@ package com.intellij.psi.impl.source.codeStyle.javadoc; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.CodeStyleSettings; -import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -26,27 +27,31 @@ import java.util.StringTokenizer; /** * Javadoc parser - * + * * @author Dmitry Skavish */ public class JDParser { - + private static final String PRE_TAG_START = "
";
   private static final String PRE_TAG_END = "
"; - + private static final String P_END_TAG = "

"; + private static final String P_START_TAG = "

"; + private static final String SELF_CLOSED_P_TAG = "

"; + private final CodeStyleSettings mySettings; - public JDParser(CodeStyleSettings settings) { + public JDParser(@NotNull CodeStyleSettings settings) { mySettings = settings; } private static final char lineSeparator = '\n'; - public JDComment parse(String text, JDComment c) { + @NotNull + public JDComment parse(@Nullable String text, @NotNull JDComment c) { if (text == null) return c; - ArrayList markers = new ArrayList(); - ArrayList l = toArray(text, "\n", markers); + List markers = new ArrayList(); + List l = toArray(text, "\n", markers); if (l == null) return c; int size = l.size(); if (size == 0) return c; @@ -73,7 +78,7 @@ public class JDParser { l.set(i, line); } - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); String tag = null; for (int i = 0; i <= size; i++) { String line = i == size ? null : l.get(i); @@ -125,43 +130,23 @@ public class JDParser { return c; } - /** - * Breaks the specified string by lineseparator into array of strings - * - * @param s the specified string - * @return array of strings (lines) - */ - public ArrayList toArrayByNL(String s) { - return toArray(s, "\n", null); - } - - /** - * Breaks the specified string by comma into array of strings - * - * @param s the specified string - * @return list of strings - */ - public ArrayList toArrayByComma(String s) { - return toArray(s, ",", null); - } - /** * Breaks the specified string by the specified separators into array of strings - * + * * @param s the specified string * @param separators the specified separators * @param markers if this parameter is not null then it will be filled with Boolean values: - * true if the correspoding line in returned list is inside <pre> tag, + * true if the corresponding line in returned list is inside <pre> tag, * false if it is outside * @return array of strings (lines) */ - @SuppressWarnings({"HardCodedStringLiteral"}) - private ArrayList toArray(String s, String separators, ArrayList markers) { + @Nullable + private List toArray(@Nullable String s, @NotNull String separators, @Nullable List markers) { if (s == null) return null; s = s.trim(); if (s.length() == 0) return null; boolean p2nl = markers != null && mySettings.JD_P_AT_EMPTY_LINES; - ArrayList list = new ArrayList(); + List list = new ArrayList(); StringTokenizer st = new StringTokenizer(s, separators, true); boolean first = true; int preCount = 0; @@ -170,7 +155,7 @@ public class JDParser { String token = st.nextToken(); curPos += token.length(); - if (separators.indexOf(token) >= 0) { + if (separators.contains(token)) { if (!first) { list.add(""); if (markers != null) markers.add(Boolean.valueOf(preCount > 0)); @@ -180,7 +165,7 @@ public class JDParser { else { first = true; if (p2nl) { - if (isParaTag(token) && s.indexOf("

", curPos) < 0) { + if (isParaTag(token) && s.indexOf(P_END_TAG, curPos) < 0) { list.add(""); markers.add(Boolean.valueOf(preCount > 0)); continue; @@ -191,9 +176,9 @@ public class JDParser { list.add(token); if (markers != null) { - if (token.indexOf("
") >= 0) preCount++;
+          if (token.contains(PRE_TAG_START)) preCount++;
           markers.add(Boolean.valueOf(preCount > 0));
-          if (token.indexOf("
") >= 0) preCount--; + if (token.contains(PRE_TAG_END)) preCount--; } } @@ -201,56 +186,30 @@ public class JDParser { return list; } - @SuppressWarnings({"HardCodedStringLiteral"}) - private boolean isParaTag(final String token) { + private static boolean isParaTag(@NotNull final String token) { String withoutWS = removeWhiteSpacesFrom(token).toLowerCase(); - return withoutWS.equals("

") || withoutWS.equals("

"); + return withoutWS.equals(SELF_CLOSED_P_TAG) || withoutWS.equals(P_START_TAG); } - private String removeWhiteSpacesFrom(final String token) { - final StringBuffer result = new StringBuffer(); + @NotNull + private static String removeWhiteSpacesFrom(@NotNull final String token) { + final StringBuilder result = new StringBuilder(); for (char c : token.toCharArray()) { if (c != ' ') result.append(c); } return result.toString(); } - public static String toLines(ArrayList l) { - if (l == null || l.size() == 0) return null; - StringBuffer sb = new StringBuffer(); - for (Object aL : l) { - String s = (String)aL; - if (sb.length() > 0) { - sb.append(lineSeparator); - } - sb.append(s); - } - return sb.toString(); - } - - public static String toCommaSeparated(ArrayList l) { - if (l == null || l.size() == 0) return null; - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < l.size(); i++) { - String s = l.get(i); - if (i != 0) { - sb.append(", "); - } - sb.append(s); - } - return sb.toString(); - } - /** - * Processes all lines (char sequences separated by line feed symbol) from the given string slitting them if necessary - * ensuring that every returned line contains less symbols than the given width. - * + * Processes all lines (char sequences separated by line feed symbol) from the given string slitting them if necessary + * ensuring that every returned line contains less symbols than the given width. + * * @param s the specified string * @param width width of the wrapped text * @return array of strings (lines) */ @Nullable - private List toArrayWrapping(String s, int width) { + private List toArrayWrapping(@Nullable String s, int width) { List list = new ArrayList(); List> pairs = splitToParagraphs(s); if (pairs == null) { @@ -305,7 +264,7 @@ public class JDParser { /** * Processes given string and produces on its basis set of pairs like '(string; flag)' where 'string' * is interested line and 'flag' indicates if it is wrapped to {@code

} tag.
-   * 
+   *
    * @param s   string to process
    * @return    processing result
    */
@@ -313,15 +272,16 @@ public class JDParser {
   private List> splitToParagraphs(@Nullable String s) {
     if (s == null) return null;
     s = s.trim();
-    if (s == null /* just to make inspection happy*/ || s.isEmpty()) return null;
+    if (s.isEmpty()) return null;
 
     List> result = new ArrayList>();
-    
+
     StringBuilder sb = new StringBuilder();
-    ArrayList markers = new ArrayList();
-    ArrayList list = toArray(s, "\n", markers);
+    List markers = new ArrayList();
+    List list = toArray(s, "\n", markers);
     Boolean[] marks = markers.toArray(new Boolean[markers.size()]);
     markers.clear();
+    assert list != null;
     for (int i = 0; i < list.size(); i++) {
       String s1 = list.get(i);
       if (marks[i].booleanValue()) {
@@ -353,27 +313,17 @@ public class JDParser {
     }
     return result;
   }
-  
-  static abstract class TagParser {
+
+  abstract static class TagParser {
 
     abstract boolean parse(String tag, String line, JDComment c);
   }
 
-  private static final @NonNls String SEE_TAG = "see";
-  private static final @NonNls String SINCE_TAG = "since";
-  private static final @NonNls String VERSION_TAG = "version";
-  private static final @NonNls String DEPRECATED_TAG = "deprecated";
-  private static final @NonNls String RETURN_TAG = "return";
-  private static final @NonNls String PARAM_TAG = "param";
-  private static final @NonNls String THROWS_TAG = "throws";
-  private static final @NonNls String EXCEPTION_TAG = "exception";
-  private static final @NonNls String AUTHOR_TAG = "author";
-
   private static final TagParser[] tagParsers = {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = SEE_TAG.equals(tag);
+        boolean isMyTag = JDTag.SEE.tagEqual(tag);
         if (isMyTag) {
           c.addSeeAlso(line);
         }
@@ -383,7 +333,7 @@ public class JDParser {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = SINCE_TAG.equals(tag);
+        boolean isMyTag = JDTag.SINCE.tagEqual(tag);
         if (isMyTag) {
           c.setSince(line);
         }
@@ -393,7 +343,7 @@ public class JDParser {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = c instanceof JDClassComment && VERSION_TAG.equals(tag);
+        boolean isMyTag = c instanceof JDClassComment && JDTag.VERSION.tagEqual(tag);
         if (isMyTag) {
           ((JDClassComment)c).setVersion(line);
         }
@@ -403,7 +353,7 @@ public class JDParser {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = DEPRECATED_TAG.equals(tag);
+        boolean isMyTag = JDTag.DEPRECATED.tagEqual(tag);
         if (isMyTag) {
           c.setDeprecated(line);
         }
@@ -413,7 +363,7 @@ public class JDParser {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = c instanceof JDMethodComment && RETURN_TAG.equals(tag);
+        boolean isMyTag = c instanceof JDMethodComment && JDTag.RETURN.tagEqual(tag);
         if (isMyTag) {
           JDMethodComment mc = (JDMethodComment)c;
           mc.setReturnTag(line);
@@ -424,7 +374,7 @@ public class JDParser {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = c instanceof JDParamListOwnerComment && PARAM_TAG.equals(tag);
+        boolean isMyTag = c instanceof JDParamListOwnerComment && JDTag.PARAM.tagEqual(tag);
         if (isMyTag) {
           JDParamListOwnerComment mc = (JDParamListOwnerComment)c;
           int idx;
@@ -447,7 +397,7 @@ public class JDParser {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = c instanceof JDMethodComment && (THROWS_TAG.equals(tag) || EXCEPTION_TAG.equals(tag));
+        boolean isMyTag = c instanceof JDMethodComment && (JDTag.THROWS.tagEqual(tag) || JDTag.EXCEPTION.tagEqual(tag));
         if (isMyTag) {
           JDMethodComment mc = (JDMethodComment)c;
           int idx;
@@ -470,7 +420,7 @@ public class JDParser {
     new TagParser() {
       @Override
       boolean parse(String tag, String line, JDComment c) {
-        boolean isMyTag = c instanceof JDClassComment && AUTHOR_TAG.equals(tag);
+        boolean isMyTag = c instanceof JDClassComment && JDTag.AUTHOR.tagEqual(tag);
         if (isMyTag) {
           JDClassComment cl = (JDClassComment)c;
           cl.addAuthor(line.trim());
@@ -478,33 +428,72 @@ public class JDParser {
         return isMyTag;
       }
     },
-/*        new TagParser() {
-            boolean parse( String tag, String line, JDComment c ) {
-                XDTag xdtag = XDTag.parse(tag, line);
-                if( xdtag != null ) {
-                    c.addXDocTag(xdtag);
-                }
-                return xdtag != null;
-            }
-        },*/
   };
 
-  protected StringBuffer splitIntoCLines(String s, String prefix) {
-    return splitIntoCLines(s, prefix, true);
+  /**
+   * @see JDParser#formatJDTagDescription(String, CharSequence, boolean, int)
+   */
+  @NotNull
+  protected StringBuilder formatJDTagDescription(@Nullable String s, @NotNull CharSequence prefix) {
+    return formatJDTagDescription(s, prefix, false, 0);
   }
 
-  protected StringBuffer splitIntoCLines(String s, String prefix, boolean add_prefix_to_first_line) {
-    return splitIntoCLines(s, new StringBuffer(prefix), add_prefix_to_first_line);
+  private static boolean lineHasUnclosedPreTag(@NotNull String line) {
+    return StringUtil.getOccurrenceCount(line, PRE_TAG_START) > StringUtil.getOccurrenceCount(line, PRE_TAG_END);
   }
 
-  protected StringBuffer splitIntoCLines(String s, StringBuffer prefix, boolean add_prefix_to_first_line) {
-    @NonNls StringBuffer sb = new StringBuffer();
-    if (add_prefix_to_first_line) {
-      sb.append(prefix);
+  /**
+   * Returns formatted JavaDoc tag description, according to selected configuration
+   * @param str JavaDoc tag description
+   * @param prefix JavaDoc prefix(like "      *  ") which will be appended to every new line
+   * @param firstLineShorter flag if first line should be shorter (has another prefix length than other lines)
+   * @param firstLinePrefixLength first line prefix length
+   * @return formatted JavaDoc tag description
+   */
+  @NotNull
+  protected StringBuilder formatJDTagDescription(@Nullable String str,
+                                                 @NotNull CharSequence prefix,
+                                                 boolean firstLineShorter,
+                                                 int firstLinePrefixLength)
+  {
+    StringBuilder sb = new StringBuilder();
+    List list;
+
+    //If wrap comments selected, comments should be wrapped by the right margin
+    if (mySettings.WRAP_COMMENTS) {
+      list = toArrayWrapping(str, mySettings.RIGHT_MARGIN - prefix.length());
+
+      if (firstLineShorter
+          && list != null && !list.isEmpty()
+          && list.get(0).length() > mySettings.RIGHT_MARGIN - firstLinePrefixLength)
+      {
+        list = new ArrayList();
+        //want the first line to be shorter, according to it's prefix
+        String firstLine = toArrayWrapping(str, mySettings.RIGHT_MARGIN - firstLinePrefixLength).get(0);
+        //so now first line is exactly same width we need
+        list.add(firstLine);
+        str = str.substring(firstLine.length());
+        //actually there is one more problem - when first line has unclosed 
 tag, substring should be processed if it's inside 
+        boolean unclosedPreTag = lineHasUnclosedPreTag(firstLine);
+        if (unclosedPreTag) {
+          str = PRE_TAG_START + str.replaceAll("^\\s+", "");
+        }
+
+        //getting all another lines according to their prefix
+        List subList = toArrayWrapping(str, mySettings.RIGHT_MARGIN - prefix.length());
+
+        //removing pre tag
+        if (unclosedPreTag) {
+          String firstLineTagRemoved = subList.get(0).substring(PRE_TAG_START.length());
+          subList.set(0, firstLineTagRemoved);
+        }
+        list.addAll(subList);
+      }
     }
-    List list = mySettings.WRAP_COMMENTS
-                             ? toArrayWrapping(s, mySettings.RIGHT_MARGIN - prefix.length())
-                             : toArray(s, "\n", new ArrayList());
+    else {
+      list = toArray(str, "\n", new ArrayList());
+    }
+
     if (list == null) {
       sb.append('\n');
     }
@@ -515,11 +504,11 @@ public class JDParser {
         if (line.length() == 0 && !mySettings.JD_KEEP_EMPTY_LINES) continue;
         if (i != 0) sb.append(prefix);
         if (line.length() == 0 && mySettings.JD_P_AT_EMPTY_LINES && !insidePreTag) {
-          sb.append("

"); + sb.append(SELF_CLOSED_P_TAG); } else { sb.append(line); - + // We want to track if we're inside

...
in order to not generate

there. if (PRE_TAG_START.equals(line)) { insidePreTag = true; diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDTag.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDTag.java new file mode 100644 index 000000000000..1b3514533179 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDTag.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2013 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.psi.impl.source.codeStyle.javadoc; + +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * User: Lepenkin Y. + * Date: 7/1/13 + * Time: 4:15 PM + */ +public enum JDTag { + SEE("see"), + AUTHOR("author"), + VERSION("version"), + THROWS("throws"), + EXCEPTION("exception"), + RETURN("return"), + PARAM("param"), + SINCE("since"), + DEPRECATED("deprecated"); + + + @NotNull private final String myTag; + + JDTag(@NotNull String tag) { + this.myTag = tag; + } + + @NotNull + public String getDescriptionPrefix(@NotNull String prefix) { + return prefix + StringUtil.repeatSymbol(' ', getWithEndWhitespace().length()); + } + + @NotNull + public String getWithEndWhitespace() { + return "@" + myTag + " "; + } + + public boolean tagEqual(@Nullable String tag) { + return myTag.equals(tag); + } +} diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java index d7de91b90ecc..6e8ee10d4ad5 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/NameDesc.java @@ -15,29 +15,25 @@ */ package com.intellij.psi.impl.source.codeStyle.javadoc; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + /** * * @author Dmitry Skavish */ public class NameDesc { + @NotNull public final String name; + @Nullable public final String desc; - public String name; - public String desc; - private String type; - - public NameDesc(String name, String desc) { + public NameDesc(@NotNull String name, @Nullable String desc) { this.name = name; this.desc = desc; } - public NameDesc(String name, String desc, String type) { - this.name = name; - this.desc = desc; - this.type = type; - } - + @NotNull + @Override public String toString() { - if (type == null) return name; - return name + ": " + type; + return name; } } diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavadocFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavadocFormatterTest.java index b28fcbd6b50a..28e4de5099f6 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavadocFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavadocFormatterTest.java @@ -216,4 +216,140 @@ public class JavadocFormatterTest extends AbstractJavaFormatterTest { doTextTest(before, after); } + + public void testReturnTagAlignment() throws Exception { + getSettings().getRootSettings().ENABLE_JAVADOC_FORMATTING = true; + getSettings().getRootSettings().RIGHT_MARGIN = 80; + getSettings().getRootSettings().JD_LEADING_ASTERISKS_ARE_ENABLED = true; + getSettings().getRootSettings().WRAP_COMMENTS = true; + getSettings().getRootSettings().getCommonSettings(JavaLanguage.INSTANCE).WRAP_LONG_LINES = true; + + String before = " /**\n" + + " * @return this is a return value documentation with a very long description that is longer than the right margin. It is more than 200 characters long, not including the comment indent and the asterisk characters, which should be greater than any sane right margin.\n" + + " */\n" + + " public int method(int parameter) {\n" + + " return 0;\n" + + " }\n"; + + String after = "/**\n" + + " * @return this is a return value documentation with a very long description\n" + + " * that is longer than the right margin. It is more than 200 characters\n" + + " * long, not including the comment indent and the asterisk characters, which\n" + + " * should be greater than any sane right margin.\n" + + " */\n" + + "public int method(int parameter) {\n" + + " return 0;\n" + + "}\n"; + + doClassTest(before, after); + } + + + public void testReturnTagAlignmentWithPreTagOnFirstLine() throws Exception { + getSettings().getRootSettings().ENABLE_JAVADOC_FORMATTING = true; + getSettings().getRootSettings().RIGHT_MARGIN = 80; + getSettings().getRootSettings().JD_LEADING_ASTERISKS_ARE_ENABLED = true; + getSettings().getRootSettings().WRAP_COMMENTS = true; + getSettings().getRootSettings().getCommonSettings(JavaLanguage.INSTANCE).WRAP_LONG_LINES = true; + + String before = " /**\n" + + " * @return

this is a return value documentation with a very long description\n" +
+                    "     * that is longer than the right margin.
\n" + + " */\n" + + " public int method(int parameter) {\n" + + " return 0;\n" + + " }"; + + String after = "/**\n" + + " * @return
this is a return value documentation with a very long\n" +
+                   " * description\n" +
+                   " * that is longer than the right margin.
\n" + + " */\n" + + "public int method(int parameter) {\n" + + " return 0;\n" + + "}"; + + doClassTest(before, after); + } + + public void testSeeTagAlignment() throws Exception { + getSettings().getRootSettings().ENABLE_JAVADOC_FORMATTING = true; + getSettings().getRootSettings().RIGHT_MARGIN = 80; + getSettings().getRootSettings().JD_LEADING_ASTERISKS_ARE_ENABLED = true; + getSettings().getRootSettings().WRAP_COMMENTS = true; + getSettings().getRootSettings().getCommonSettings(JavaLanguage.INSTANCE).WRAP_LONG_LINES = true; + + String before = " /**\n" + + " * @see this is an additional documentation with a very long description that is longer than the right margin. It is more than 200 characters long, not including the comment indent and the asterisk characters which should be greater than any sane right margin\n" + + " */\n" + + " public int method(int parameter) {\n" + + " return 0;\n" + + " }"; + + String after = "/**\n" + + " * @see this is an additional documentation with a very long description\n" + + " * that is longer than the right margin. It is more than 200 characters\n" + + " * long, not including the comment indent and the asterisk characters which\n" + + " * should be greater than any sane right margin\n" + + " */\n" + + "public int method(int parameter) {\n" + + " return 0;\n" + + "}"; + + doClassTest(before, after); + } + + public void testDummySinceTagAlignment() throws Exception { + getSettings().getRootSettings().ENABLE_JAVADOC_FORMATTING = true; + getSettings().getRootSettings().RIGHT_MARGIN = 80; + getSettings().getRootSettings().JD_LEADING_ASTERISKS_ARE_ENABLED = true; + getSettings().getRootSettings().WRAP_COMMENTS = true; + getSettings().getRootSettings().getCommonSettings(JavaLanguage.INSTANCE).WRAP_LONG_LINES = true; + + String before = " /**\n" + + " * @since this is an additional documentation with a very long description that is longer than the right margin. It is more than 200 characters long, not including the comment indent and the asterisk characters which should be greater than any sane right margin\n" + + " */\n" + + " public int method(int parameter) {\n" + + " return 0;\n" + + " }"; + + String after = "/**\n" + + " * @since this is an additional documentation with a very long description\n" + + " * that is longer than the right margin. It is more than 200 characters\n" + + " * long, not including the comment indent and the asterisk characters which\n" + + " * should be greater than any sane right margin\n" + + " */\n" + + "public int method(int parameter) {\n" + + " return 0;\n" + + "}"; + + doClassTest(before, after); + } + + public void testDummyDeprecatedTagAlignment() throws Exception { + getSettings().getRootSettings().ENABLE_JAVADOC_FORMATTING = true; + getSettings().getRootSettings().RIGHT_MARGIN = 80; + getSettings().getRootSettings().JD_LEADING_ASTERISKS_ARE_ENABLED = true; + getSettings().getRootSettings().WRAP_COMMENTS = true; + getSettings().getRootSettings().getCommonSettings(JavaLanguage.INSTANCE).WRAP_LONG_LINES = true; + + String before = " /**\n" + + " * @deprecated this is an additional documentation with a very long description that is longer than the right margin. It is more than 200 characters long, not including the comment indent and the asterisk characters which should be greater than any sane right margin\n" + + " */\n" + + " public int method(int parameter) {\n" + + " return 0;\n" + + " }"; + + String after = "/**\n" + + " * @deprecated this is an additional documentation with a very long\n" + + " * description that is longer than the right margin. It is more than 200\n" + + " * characters long, not including the comment indent and the asterisk\n" + + " * characters which should be greater than any sane right margin\n" + + " */\n" + + "public int method(int parameter) {\n" + + " return 0;\n" + + "}"; + + doClassTest(before, after); + } } diff --git a/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationTypeBase.java b/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationTypeBase.java index e47eb7877d32..b6ab46753b3e 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationTypeBase.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationTypeBase.java @@ -16,12 +16,10 @@ package com.intellij.execution.configurations; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; /** * @author yole @@ -44,10 +42,7 @@ public abstract class ConfigurationTypeBase implements ConfigurationType { } protected void addFactory(ConfigurationFactory factory) { - List newFactories = new ArrayList(myFactories.length + 1); - Collections.addAll(newFactories, myFactories); - newFactories.add(factory); - myFactories = newFactories.toArray(new ConfigurationFactory[newFactories.size()]); + myFactories = ArrayUtil.append(myFactories, factory); } @Override diff --git a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml index 250b0110975b..fd2ba06e0064 100644 --- a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml +++ b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml @@ -88,6 +88,7 @@ + diff --git a/platform/platform-resources/src/META-INF/RemoteServers.xml b/platform/platform-resources/src/META-INF/RemoteServers.xml new file mode 100644 index 000000000000..89386b66db40 --- /dev/null +++ b/platform/platform-resources/src/META-INF/RemoteServers.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + com.intellij.remoteServer.run.DeployToServerConfigurationTypesRegistrar + + + \ No newline at end of file diff --git a/platform/remote-servers/api/remote-servers-api.iml b/platform/remote-servers/api/remote-servers-api.iml new file mode 100644 index 000000000000..deb49db5a58f --- /dev/null +++ b/platform/remote-servers/api/remote-servers-api.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java new file mode 100644 index 000000000000..c3b2029dd957 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java @@ -0,0 +1,41 @@ +package com.intellij.remoteServer; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.project.Project; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import com.intellij.remoteServer.deployment.Deployer; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @author nik + */ +public abstract class ServerType { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.remoteServer.type"); + private final String myId; + + protected ServerType(String id) { + myId = id; + } + + public final String getId() { + return myId; + } + + @NotNull + public abstract String getPresentableName(); + + @NotNull + public abstract Icon getIcon(); + + @NotNull + public abstract C createDefaultConfiguration(); + + @NotNull + public abstract UnnamedConfigurable createConfigurable(@NotNull C configuration); + + @NotNull + public abstract Deployer createDeployer(Project project); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/RemoteServer.java b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/RemoteServer.java new file mode 100644 index 000000000000..e845adec0be6 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/RemoteServer.java @@ -0,0 +1,20 @@ +package com.intellij.remoteServer.configuration; + +import com.intellij.remoteServer.ServerType; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public interface RemoteServer { + @NotNull + String getName(); + + @NotNull + ServerType getType(); + + @NotNull + C getConfiguration(); + + void setName(String name); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/RemoteServersManager.java b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/RemoteServersManager.java new file mode 100644 index 000000000000..5c29088d9cd3 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/RemoteServersManager.java @@ -0,0 +1,30 @@ +package com.intellij.remoteServer.configuration; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.remoteServer.ServerType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * @author nik + */ +public abstract class RemoteServersManager { + public static RemoteServersManager getInstance() { + return ServiceManager.getService(RemoteServersManager.class); + } + + public abstract List> getServers(); + + public abstract List> getServers(@NotNull ServerType type); + + @Nullable + public abstract RemoteServer findByName(@NotNull String name, @NotNull ServerType type); + + public abstract RemoteServer createServer(@NotNull ServerType type, @NotNull String name); + + public abstract void addServer(RemoteServer server); + + public abstract void removeServer(RemoteServer server); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/ServerConfiguration.java b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/ServerConfiguration.java new file mode 100644 index 000000000000..255bdb834480 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/configuration/ServerConfiguration.java @@ -0,0 +1,10 @@ +package com.intellij.remoteServer.configuration; + +import com.intellij.openapi.components.PersistentStateComponent; + +/** + * @author nik + */ +public abstract class ServerConfiguration { + public abstract PersistentStateComponent getSerializer(); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/ArtifactDeploymentSource.java b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/ArtifactDeploymentSource.java new file mode 100644 index 000000000000..1a3838e9e336 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/ArtifactDeploymentSource.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2013 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.remoteServer.deployment; + +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactPointer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public interface ArtifactDeploymentSource extends DeploymentSource { + @NotNull + ArtifactPointer getArtifactPointer(); + + @Nullable + Artifact getArtifact(); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/Deployer.java b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/Deployer.java new file mode 100644 index 000000000000..c16322cecfcc --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/Deployer.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2013 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.remoteServer.deployment; + +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public abstract class Deployer { + @NotNull + public abstract List getAvailableDeploymentSources(); + + public abstract void startDeployment(@NotNull RemoteServer server, @NotNull DeploymentSource source); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/DeploymentSource.java b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/DeploymentSource.java new file mode 100644 index 000000000000..123ae3eab3a3 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/DeploymentSource.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2013 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.remoteServer.deployment; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.io.File; + +/** + * @author nik + */ +public interface DeploymentSource { + @Nullable + File getFile(); + + @Nullable + String getFilePath(); + + @NotNull + String getPresentableName(); + + @Nullable + Icon getIcon(); + + boolean isValid(); +} diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/DeploymentSourceUtil.java b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/DeploymentSourceUtil.java new file mode 100644 index 000000000000..1d10281e54c0 --- /dev/null +++ b/platform/remote-servers/api/src/com/intellij/remoteServer/deployment/DeploymentSourceUtil.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2013 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.remoteServer.deployment; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.packaging.artifacts.ArtifactPointer; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public abstract class DeploymentSourceUtil { + public static DeploymentSourceUtil getInstance() { + return ServiceManager.getService(DeploymentSourceUtil.class); + } + + @NotNull + public abstract ArtifactDeploymentSource createArtifactDeploymentSource(@NotNull ArtifactPointer artifactPointer); + + public abstract DeploymentSource loadDeploymentSource(@NotNull Element element, @NotNull Project project); + + public abstract void saveDeploymentSource(@NotNull DeploymentSource source, @NotNull Element element, @NotNull Project project); +} diff --git a/platform/remote-servers/impl/remote-servers-impl.iml b/platform/remote-servers/impl/remote-servers-impl.iml new file mode 100644 index 000000000000..51c6c6f8de63 --- /dev/null +++ b/platform/remote-servers/impl/remote-servers-impl.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerConfigurable.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerConfigurable.java new file mode 100644 index 000000000000..6633e15d6ae5 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerConfigurable.java @@ -0,0 +1,93 @@ +package com.intellij.remoteServer.configuration.impl; + +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.ui.NamedConfigurable; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; + +/** + * @author nik + */ +public class RemoteServerConfigurable extends NamedConfigurable> { + private final UnnamedConfigurable myConfigurable; + private final RemoteServer myServer; + private String myServerName; + private boolean myNew; + + public RemoteServerConfigurable(RemoteServer server, Runnable treeUpdater, boolean isNew) { + super(true, treeUpdater); + myServer = server; + myNew = isNew; + myServerName = myServer.getName(); + C c = server.getConfiguration(); + myConfigurable = server.getType().createConfigurable(c); + } + + @Override + public RemoteServer getEditableObject() { + return myServer; + } + + @Override + public String getBannerSlogan() { + return myServer.getName(); + } + + @Override + public JComponent createOptionsPanel() { + JComponent component = myConfigurable.createComponent(); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(component, BorderLayout.NORTH); + return panel; + } + + @Nls + @Override + public String getDisplayName() { + return myServerName; + } + + @Nullable + @Override + public String getHelpTopic() { + return null; + } + + @Override + public void setDisplayName(String name) { + myServerName = name; + } + + @Override + public boolean isModified() { + return myNew || myConfigurable.isModified() || !myServerName.equals(myServer.getName()); + } + + @Override + public void apply() throws ConfigurationException { + myConfigurable.apply(); + myNew = false; + } + + @Override + public void reset() { + myConfigurable.reset(); + } + + @Override + public void disposeUIResources() { + myConfigurable.disposeUIResources(); + } + + @Nullable + @Override + public Icon getIcon(boolean expanded) { + return myServer.getType().getIcon(); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerImpl.java new file mode 100644 index 000000000000..a210be03cd2c --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerImpl.java @@ -0,0 +1,44 @@ +package com.intellij.remoteServer.configuration.impl; + +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class RemoteServerImpl implements RemoteServer { + private String myName; + private ServerType myType; + private C myConfiguration; + + public RemoteServerImpl(String name, ServerType type, C configuration) { + myName = name; + myType = type; + myConfiguration = configuration; + } + + @NotNull + @Override + public String getName() { + return myName; + } + + @NotNull + @Override + public ServerType getType() { + return myType; + } + + @NotNull + @Override + public C getConfiguration() { + return myConfiguration; + } + + @Override + public void setName(String name) { + myName = name; + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerListConfigurable.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerListConfigurable.java new file mode 100644 index 000000000000..f2ff8c96d24f --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerListConfigurable.java @@ -0,0 +1,171 @@ +package com.intellij.remoteServer.configuration.impl; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonShortcuts; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.OptionalConfigurable; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.ui.MasterDetailsComponent; +import com.intellij.openapi.ui.NamedConfigurable; +import com.intellij.openapi.util.Condition; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.RemoteServersManager; +import com.intellij.util.IconUtil; +import com.intellij.util.text.UniqueNameGenerator; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author nik + */ +public class RemoteServerListConfigurable extends MasterDetailsComponent implements OptionalConfigurable { + private final RemoteServersManager myServersManager; + + public RemoteServerListConfigurable(RemoteServersManager manager) { + myServersManager = manager; + initTree(); + } + + @Nls + @Override + public String getDisplayName() { + return "Clouds"; + } + + @Override + public void reset() { + myRoot.removeAllChildren(); + for (RemoteServer server : myServersManager.getServers()) { + addServerNode(server, false); + } + super.reset(); + } + + private MyNode addServerNode(RemoteServer server, boolean isNew) { + MyNode node = new MyNode(new RemoteServerConfigurable(server, TREE_UPDATER, isNew)); + addNode(node, myRoot); + return node; + } + + @Override + protected void processRemovedItems() { + Set> servers = new HashSet>(); + for (NamedConfigurable> configurable : getConfiguredServers()) { + servers.add(configurable.getEditableObject()); + } + + List> toDelete = new ArrayList>(); + for (RemoteServer server : myServersManager.getServers()) { + if (!servers.contains(server)) { + toDelete.add(server); + } + } + for (RemoteServer server : toDelete) { + myServersManager.removeServer(server); + } + } + + @Override + public void apply() throws ConfigurationException { + super.apply(); + Set> servers = new HashSet>(myServersManager.getServers()); + for (NamedConfigurable> configurable : getConfiguredServers()) { + RemoteServer server = configurable.getEditableObject(); + server.setName(configurable.getDisplayName()); + if (!servers.contains(server)) { + myServersManager.addServer(server); + } + } + } + + @Nullable + @Override + protected ArrayList createActions(boolean fromPopup) { + ArrayList actions = new ArrayList(); + actions.add(new AddRemoteServerGroup()); + actions.add(new MyDeleteAction()); + return actions; + } + + @Override + public boolean needDisplay() { + return ServerType.EP_NAME.getExtensions().length > 0; + } + + @Override + protected boolean wasObjectStored(Object editableObject) { + return true; + } + + private List>> getConfiguredServers() { + List>> configurables = new ArrayList>>(); + for (int i = 0; i < myRoot.getChildCount(); i++) { + MyNode node = (MyNode)myRoot.getChildAt(i); + configurables.add((NamedConfigurable>)node.getConfigurable()); + } + return configurables; + } + + private class AddRemoteServerGroup extends ActionGroup implements ActionGroupWithPreselection { + private AddRemoteServerGroup() { + super("Add", "", IconUtil.getAddIcon()); + registerCustomShortcutSet(CommonShortcuts.INSERT, myTree); + } + + @NotNull + @Override + public AnAction[] getChildren(@Nullable AnActionEvent e) { + ServerType[] serverTypes = ServerType.EP_NAME.getExtensions(); + AnAction[] actions = new AnAction[serverTypes.length]; + for (int i = 0; i < serverTypes.length; i++) { + actions[i] = new AddRemoteServerAction(serverTypes[i]); + } + return actions; + } + + @Override + public ActionGroup getActionGroup() { + return this; + } + + @Override + public int getDefaultIndex() { + return 0; + } + } + + private class AddRemoteServerAction extends DumbAwareAction { + private final ServerType myServerType; + + private AddRemoteServerAction(ServerType serverType) { + super(serverType.getPresentableName(), null, serverType.getIcon()); + myServerType = serverType; + } + + @Override + public void actionPerformed(AnActionEvent e) { + String name = UniqueNameGenerator.generateUniqueName(myServerType.getPresentableName(), new Condition() { + @Override + public boolean value(String s) { + for (NamedConfigurable> configurable : getConfiguredServers()) { + if (configurable.getDisplayName().equals(s)) { + return false; + } + } + return true; + } + }); + MyNode node = addServerNode(myServersManager.createServer(myServerType, name), true); + selectNodeInTree(node); + } + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerState.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerState.java new file mode 100644 index 000000000000..fcf6f2dc6c56 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServerState.java @@ -0,0 +1,18 @@ +package com.intellij.remoteServer.configuration.impl; + +import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.Tag; +import org.jdom.Element; + +/** +* @author nik +*/ +@Tag("remote-server") +public class RemoteServerState { + @Attribute("name") + public String myName; + @Attribute("type") + public String myTypeId; + @Tag("configuration") + public Element myConfiguration; +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServersManagerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServersManagerImpl.java new file mode 100644 index 000000000000..3065bbc9f435 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServersManagerImpl.java @@ -0,0 +1,125 @@ +package com.intellij.remoteServer.configuration.impl; + +import com.intellij.openapi.components.ComponentSerializationUtil; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.components.StoragePathMacros; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.RemoteServersManager; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; +import com.intellij.util.xmlb.XmlSerializer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author nik + */ +@State(name = "RemoteServers", storages = { + @Storage(file = StoragePathMacros.APP_CONFIG + "/remote-servers.xml") +}) +public class RemoteServersManagerImpl extends RemoteServersManager implements PersistentStateComponent { + public static final SkipDefaultValuesSerializationFilters SERIALIZATION_FILTERS = new SkipDefaultValuesSerializationFilters(); + private List> myServers = new ArrayList>(); + private List myUnknownServers = new ArrayList(); + + @Override + public List> getServers() { + return Collections.unmodifiableList(myServers); + } + + @Override + public List> getServers(@NotNull ServerType type) { + List> servers = new ArrayList>(); + for (RemoteServer server : myServers) { + if (server.getType().equals(type)) { + servers.add((RemoteServer)server); + } + } + return servers; + } + + @Nullable + @Override + public RemoteServer findByName(@NotNull String name, @NotNull ServerType type) { + for (RemoteServer server : myServers) { + if (server.getType().equals(type) && server.getName().equals(name)) { + return (RemoteServer)server; + } + } + return null; + } + + @Override + public RemoteServer createServer(@NotNull ServerType type, @NotNull String name) { + return new RemoteServerImpl(name, type, type.createDefaultConfiguration()); + } + + @Override + public void addServer(RemoteServer server) { + myServers.add(server); + } + + @Override + public void removeServer(RemoteServer server) { + myServers.remove(server); + } + + @Nullable + @Override + public RemoteServersManagerState getState() { + RemoteServersManagerState state = new RemoteServersManagerState(); + for (RemoteServer server : myServers) { + RemoteServerState serverState = new RemoteServerState(); + serverState.myName = server.getName(); + serverState.myTypeId = server.getType().getId(); + serverState.myConfiguration = XmlSerializer.serialize(server.getConfiguration().getSerializer().getState(), SERIALIZATION_FILTERS); + state.myServers.add(serverState); + } + state.myServers.addAll(myUnknownServers); + return state; + } + + @Override + public void loadState(RemoteServersManagerState state) { + myUnknownServers.clear(); + myServers.clear(); + for (RemoteServerState server : state.myServers) { + ServerType type = findServerType(server.myTypeId); + if (type == null) { + myUnknownServers.add(server); + } + else { + myServers.add(createConfiguration(type, server)); + } + } + } + + private static RemoteServerImpl createConfiguration(ServerType type, RemoteServerState server) { + C configuration = type.createDefaultConfiguration(); + PersistentStateComponent serializer = configuration.getSerializer(); + loadConfiguration(server, serializer); + return new RemoteServerImpl(server.myName, type, configuration); + } + + private static void loadConfiguration(RemoteServerState server, PersistentStateComponent serializer) { + S deserialize = (S)XmlSerializer.deserialize(server.myConfiguration, ComponentSerializationUtil.getStateClass(serializer.getClass())); + serializer.loadState(deserialize); + } + + @Nullable + private static ServerType findServerType(@NotNull String typeId) { + for (ServerType serverType : ServerType.EP_NAME.getExtensions()) { + if (serverType.getId().equals(typeId)) { + return serverType; + } + } + return null; + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServersManagerState.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServersManagerState.java new file mode 100644 index 000000000000..0f233f675354 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/configuration/impl/RemoteServersManagerState.java @@ -0,0 +1,16 @@ +package com.intellij.remoteServer.configuration.impl; + +import com.intellij.util.xmlb.annotations.AbstractCollection; +import com.intellij.util.xmlb.annotations.Property; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class RemoteServersManagerState { + @Property(surroundWithTag = false) + @AbstractCollection(surroundWithTag = false) + public List myServers = new ArrayList(); +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/deployment/impl/ArtifactDeploymentSourceImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/deployment/impl/ArtifactDeploymentSourceImpl.java new file mode 100644 index 000000000000..3be71fea8ff7 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/deployment/impl/ArtifactDeploymentSourceImpl.java @@ -0,0 +1,88 @@ +package com.intellij.remoteServer.deployment.impl; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactPointer; +import com.intellij.packaging.elements.ArtifactRootElement; +import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.remoteServer.deployment.ArtifactDeploymentSource; +import com.intellij.remoteServer.deployment.DeploymentSource; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.io.File; + +/** + * @author nik + */ +public class ArtifactDeploymentSourceImpl implements ArtifactDeploymentSource, DeploymentSource { + private final ArtifactPointer myPointer; + + public ArtifactDeploymentSourceImpl(@NotNull ArtifactPointer pointer) { + myPointer = pointer; + } + + @NotNull + @Override + public ArtifactPointer getArtifactPointer() { + return myPointer; + } + + @Override + public Artifact getArtifact() { + return myPointer.getArtifact(); + } + + @Override + public File getFile() { + final String path = getFilePath(); + return path != null ? new File(path) : null; + } + + @Override + public String getFilePath() { + final Artifact artifact = getArtifact(); + if (artifact != null) { + String outputPath = artifact.getOutputPath(); + if (outputPath != null) { + final CompositePackagingElement rootElement = artifact.getRootElement(); + if (!(rootElement instanceof ArtifactRootElement)) { + outputPath += "/" + rootElement.getName(); + } + return FileUtil.toSystemDependentName(outputPath); + } + } + return null; + } + + @NotNull + @Override + public String getPresentableName() { + return myPointer.getArtifactName(); + } + + @Override + public Icon getIcon() { + final Artifact artifact = getArtifact(); + return artifact != null ? artifact.getArtifactType().getIcon() : null; + } + + @Override + public boolean isValid() { + return getArtifact() != null; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ArtifactDeploymentSourceImpl)) return false; + + return myPointer.equals(((ArtifactDeploymentSourceImpl)o).myPointer); + + } + + @Override + public int hashCode() { + return myPointer.hashCode(); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/deployment/impl/DeploymentSourceUtilImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/deployment/impl/DeploymentSourceUtilImpl.java new file mode 100644 index 000000000000..1acb1cba85ab --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/deployment/impl/DeploymentSourceUtilImpl.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2013 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.remoteServer.deployment.impl; + +import com.intellij.openapi.project.Project; +import com.intellij.packaging.artifacts.ArtifactPointer; +import com.intellij.packaging.artifacts.ArtifactPointerManager; +import com.intellij.remoteServer.deployment.ArtifactDeploymentSource; +import com.intellij.remoteServer.deployment.DeploymentSource; +import com.intellij.remoteServer.deployment.DeploymentSourceUtil; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class DeploymentSourceUtilImpl extends DeploymentSourceUtil { + @NotNull + @Override + public ArtifactDeploymentSource createArtifactDeploymentSource(@NotNull ArtifactPointer artifactPointer) { + return new ArtifactDeploymentSourceImpl(artifactPointer); + } + + @Override + public DeploymentSource loadDeploymentSource(@NotNull Element element, @NotNull Project project) { + ArtifactPointerManager artifactPointerManager = ArtifactPointerManager.getInstance(project); + Element artifact = element.getChild("artifact"); + return createArtifactDeploymentSource(artifactPointerManager.createPointer(artifact.getAttributeValue("name"))); + } + + @Override + public void saveDeploymentSource(@NotNull DeploymentSource source, @NotNull Element element, @NotNull Project project) { + if (source instanceof ArtifactDeploymentSource) { + String artifactName = ((ArtifactDeploymentSource)source).getArtifactPointer().getArtifactName(); + element.addContent(new Element("artifact").setAttribute("name", artifactName)); + } + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerConfigurationType.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerConfigurationType.java new file mode 100644 index 000000000000..166b6c2c464b --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerConfigurationType.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2013 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.remoteServer.run; + +import com.intellij.execution.configuration.ConfigurationFactoryEx; +import com.intellij.execution.configurations.ConfigurationTypeBase; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.project.Project; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.RemoteServersManager; +import com.intellij.remoteServer.deployment.DeploymentSource; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author nik + */ +public class DeployToServerConfigurationType extends ConfigurationTypeBase { + private ServerType myServerType; + + public DeployToServerConfigurationType(ServerType serverType) { + super(serverType.getId() + "-deploy", serverType.getPresentableName() + " Deployment", + "Deploy to " + serverType.getPresentableName() + " run configuration", serverType.getIcon()); + addFactory(new DeployToServerConfigurationFactory()); + myServerType = serverType; + } + + public class DeployToServerConfigurationFactory extends ConfigurationFactoryEx { + public DeployToServerConfigurationFactory() { + super(DeployToServerConfigurationType.this); + } + + @Override + public void onNewConfigurationCreated(@NotNull RunConfiguration configuration) { + DeployToServerRunConfiguration deployConfiguration = (DeployToServerRunConfiguration)configuration; + if (deployConfiguration.getServerName() == null) { + RemoteServer server = ContainerUtil.getFirstItem(RemoteServersManager.getInstance().getServers(myServerType)); + if (server != null) { + deployConfiguration.setServerName(server.getName()); + } + } + + if (deployConfiguration.getDeploymentSource() == null) { + List sources = deployConfiguration.getDeployer().getAvailableDeploymentSources(); + DeploymentSource source = ContainerUtil.getFirstItem(sources); + if (source != null) { + deployConfiguration.setDeploymentSource(source); + } + } + } + + @Override + public RunConfiguration createTemplateConfiguration(Project project) { + return new DeployToServerRunConfiguration(project, this, "", myServerType); + } + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerConfigurationTypesRegistrar.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerConfigurationTypesRegistrar.java new file mode 100644 index 000000000000..422cc5c6523e --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerConfigurationTypesRegistrar.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 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.remoteServer.run; + +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.extensions.ExtensionPoint; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.remoteServer.ServerType; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class DeployToServerConfigurationTypesRegistrar implements ApplicationComponent { + @Override + public void initComponent() { + //todo[nik] improve this: configuration types should be loaded lazily + ExtensionPoint point = Extensions.getRootArea().getExtensionPoint(ConfigurationType.CONFIGURATION_TYPE_EP); + for (ServerType serverType : ServerType.EP_NAME.getExtensions()) { + point.registerExtension(new DeployToServerConfigurationType(serverType)); + } + } + + @Override + public void disposeComponent() { + } + + @NotNull + @Override + public String getComponentName() { + return "DeployToServerConfigurationTypesRegistrar"; + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerRunConfiguration.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerRunConfiguration.java new file mode 100644 index 000000000000..6ba8cf1a3068 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerRunConfiguration.java @@ -0,0 +1,127 @@ +/* + * Copyright 2000-2013 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.remoteServer.run; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.RunConfigurationBase; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.configurations.RuntimeConfigurationException; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.RemoteServersManager; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import com.intellij.remoteServer.deployment.Deployer; +import com.intellij.remoteServer.deployment.DeploymentSource; +import com.intellij.remoteServer.deployment.DeploymentSourceUtil; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class DeployToServerRunConfiguration extends RunConfigurationBase { + public static final String SERVER_NAME_ATTRIBUTE = "server-name"; + public static final String SOURCE_ELEMENT = "source"; + private final ServerType myServerType; + private final Deployer myDeployer; + private String myServerName; + private DeploymentSource myDeploymentSource; + + public DeployToServerRunConfiguration(Project project, ConfigurationFactory factory, String name, ServerType serverType) { + super(project, factory, name); + myServerType = serverType; + myDeployer = myServerType.createDeployer(project); + } + + public String getServerName() { + return myServerName; + } + + @NotNull + public Deployer getDeployer() { + return myDeployer; + } + + @Override + public SettingsEditor getConfigurationEditor() { + return new DeployToServerSettingsEditor(myServerType, myDeployer, getProject()); + } + + @Nullable + @Override + public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { + String serverName = getServerName(); + if (serverName == null) { + throw new ExecutionException("Server is not specified"); + } + + RemoteServer server = RemoteServersManager.getInstance().findByName(serverName, myServerType); + if (server == null) { + throw new ExecutionException("Server '" + serverName + " not found"); + } + + if (myDeploymentSource == null) { + throw new ExecutionException("Deployment is not selected"); + } + + return new DeployToServerState(env, myDeployer, server, myDeploymentSource); + } + + @Override + public void checkConfiguration() throws RuntimeConfigurationException { + } + + public void setServerName(String serverName) { + myServerName = serverName; + } + + public DeploymentSource getDeploymentSource() { + return myDeploymentSource; + } + + public void setDeploymentSource(DeploymentSource deploymentSource) { + myDeploymentSource = deploymentSource; + } + + @Override + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + myServerName = element.getAttributeValue(SERVER_NAME_ATTRIBUTE); + Element sourceElement = element.getChild(SOURCE_ELEMENT); + myDeploymentSource = sourceElement != null ? DeploymentSourceUtil.getInstance().loadDeploymentSource(sourceElement, getProject()) : null; + } + + @Override + public void writeExternal(Element element) throws WriteExternalException { + if (myServerName != null) { + element.setAttribute(SERVER_NAME_ATTRIBUTE, myServerName); + } + if (myDeploymentSource != null) { + Element source = new Element(SOURCE_ELEMENT); + DeploymentSourceUtil.getInstance().saveDeploymentSource(myDeploymentSource, source, getProject()); + element.addContent(source); + } + super.writeExternal(element); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerRunner.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerRunner.java new file mode 100644 index 000000000000..a4b9008c5183 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerRunner.java @@ -0,0 +1,22 @@ +package com.intellij.remoteServer.run; + +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.runners.DefaultProgramRunner; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public class DeployToServerRunner extends DefaultProgramRunner { + @NotNull + @Override + public String getRunnerId() { + return "DeployToServer"; + } + + @Override + public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) { + return executorId.equals(DefaultRunExecutor.EXECUTOR_ID) && profile instanceof DeployToServerRunConfiguration; + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerSettingsEditor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerSettingsEditor.java new file mode 100644 index 000000000000..a2283cb1c024 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerSettingsEditor.java @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2013 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.remoteServer.run; + +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.RemoteServersManager; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import com.intellij.remoteServer.deployment.Deployer; +import com.intellij.remoteServer.deployment.DeploymentSource; +import com.intellij.ui.ColoredListCellRendererWrapper; +import com.intellij.ui.ListCellRendererWrapper; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.SortedComboBoxModel; +import com.intellij.util.ui.FormBuilder; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.Comparator; + +/** + * @author nik + */ +public class DeployToServerSettingsEditor extends SettingsEditor { + private ComboBox myServerComboBox; + private ComboBox mySourceComboBox; + private final SortedComboBoxModel myServerListModel; + private final SortedComboBoxModel mySourceListModel; + + public DeployToServerSettingsEditor(final ServerType type, Deployer deployer, Project project) { + myServerListModel = new SortedComboBoxModel(String.CASE_INSENSITIVE_ORDER); + for (RemoteServer server : RemoteServersManager.getInstance().getServers(type)) { + myServerListModel.add(server.getName()); + } + + myServerComboBox = new ComboBox(myServerListModel); + myServerComboBox.setRenderer(new ColoredListCellRendererWrapper() { + @Override + protected void doCustomize(JList list, String value, int index, boolean selected, boolean hasFocus) { + if (value == null) return; + SimpleTextAttributes attributes = RemoteServersManager.getInstance().findByName(value, type) == null + ? SimpleTextAttributes.ERROR_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES; + append(value, attributes); + } + }); + + mySourceListModel = new SortedComboBoxModel(new Comparator() { + @Override + public int compare(DeploymentSource o1, DeploymentSource o2) { + return o1.getPresentableName().compareToIgnoreCase(o2.getPresentableName()); + } + }); + mySourceListModel.addAll(deployer.getAvailableDeploymentSources()); + mySourceComboBox = new ComboBox(mySourceListModel); + mySourceComboBox.setRenderer(new ListCellRendererWrapper() { + @Override + public void customize(JList list, DeploymentSource value, int index, boolean selected, boolean hasFocus) { + if (value == null) return; + setIcon(value.getIcon()); + setText(value.getPresentableName()); + } + }); + } + + @Override + protected void resetEditorFrom(DeployToServerRunConfiguration configuration) { + String serverName = configuration.getServerName(); + if (serverName != null && !myServerListModel.getItems().contains(serverName)) { + myServerListModel.add(serverName); + } + myServerComboBox.setSelectedItem(serverName); + mySourceComboBox.setSelectedItem(configuration.getDeploymentSource()); + } + + @Override + protected void applyEditorTo(DeployToServerRunConfiguration configuration) throws ConfigurationException { + configuration.setServerName(myServerListModel.getSelectedItem()); + configuration.setDeploymentSource(mySourceListModel.getSelectedItem()); + } + + @NotNull + @Override + protected JComponent createEditor() { + return FormBuilder.createFormBuilder() + .addLabeledComponent("Server:", myServerComboBox) + .addLabeledComponent("Deployment:", mySourceComboBox) + .getPanel(); + } + + @Override + protected void disposeEditor() { + + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerState.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerState.java new file mode 100644 index 000000000000..ec88486bcdcb --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/run/DeployToServerState.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2013 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.remoteServer.run; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.ConfigurationPerRunnerSettings; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.configurations.RunnerSettings; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import com.intellij.remoteServer.deployment.Deployer; +import com.intellij.remoteServer.deployment.DeploymentSource; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class DeployToServerState implements RunProfileState { + private final ExecutionEnvironment myExecutionEnvironment; + @NotNull private final Deployer myDeployer; + @NotNull private final RemoteServer myServer; + @NotNull private final DeploymentSource mySource; + + public DeployToServerState(@NotNull ExecutionEnvironment executionEnvironment, + @NotNull Deployer deployer, + @NotNull RemoteServer server, + @NotNull DeploymentSource deploymentSource) { + myExecutionEnvironment = executionEnvironment; + myDeployer = deployer; + myServer = server; + mySource = deploymentSource; + } + + @Nullable + @Override + public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException { + myDeployer.startDeployment(myServer, mySource); + return null; + } + + @Override + public RunnerSettings getRunnerSettings() { + return myExecutionEnvironment.getRunnerSettings(); + } + + @Override + public ConfigurationPerRunnerSettings getConfigurationSettings() { + return myExecutionEnvironment.getConfigurationSettings(); + } +} diff --git a/plugins/google-app-engine/google-app-engine.iml b/plugins/google-app-engine/google-app-engine.iml index 52217861ad17..ab104003fd25 100644 --- a/plugins/google-app-engine/google-app-engine.iml +++ b/plugins/google-app-engine/google-app-engine.iml @@ -24,6 +24,7 @@ + diff --git a/plugins/google-app-engine/resources/META-INF/google-app-engine-plugin.xml b/plugins/google-app-engine/resources/META-INF/google-app-engine-plugin.xml index 9ce7afc50bb8..c8853454480d 100644 --- a/plugins/google-app-engine/resources/META-INF/google-app-engine-plugin.xml +++ b/plugins/google-app-engine/resources/META-INF/google-app-engine-plugin.xml @@ -22,6 +22,8 @@ + + diff --git a/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java b/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java index a6dc462fa684..2e7dae2262ea 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java @@ -16,6 +16,7 @@ package com.intellij.appengine.actions; import com.intellij.CommonBundle; +import com.intellij.appengine.cloud.AppEngineServerConfiguration; import com.intellij.appengine.descriptor.dom.AppEngineWebApp; import com.intellij.appengine.facet.AppEngineAccountDialog; import com.intellij.appengine.facet.AppEngineFacet; @@ -105,7 +106,9 @@ public class AppEngineUploader { } @Nullable - public static AppEngineUploader createUploader(@NotNull Project project, @NotNull Artifact artifact) { + public static AppEngineUploader createUploader(@NotNull Project project, + @NotNull Artifact artifact, + @Nullable AppEngineServerConfiguration configuration) { final String explodedPath = artifact.getOutputPath(); if (explodedPath == null) { Messages.showErrorDialog(project, "Output path isn't specified for '" + artifact.getName() + "' artifact", CommonBundle.getErrorTitle()); @@ -150,7 +153,7 @@ public class AppEngineUploader { String password = null; String email = null; try { - email = AppEngineAccountDialog.getStoredEmail(project); + email = AppEngineAccountDialog.getStoredEmail(configuration, project); password = AppEngineAccountDialog.getStoredPassword(project, email); } catch (PasswordSafeException e) { @@ -158,7 +161,7 @@ public class AppEngineUploader { LOG.info(e); } if (StringUtil.isEmpty(email) || StringUtil.isEmpty(password)) { - final AppEngineAccountDialog dialog = new AppEngineAccountDialog(project); + final AppEngineAccountDialog dialog = new AppEngineAccountDialog(project, configuration); dialog.show(); if (!dialog.isOK()) return null; diff --git a/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java b/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java index df6daaf5cbd3..15fb4051d1db 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java @@ -57,7 +57,7 @@ public class UploadApplicationAction extends AnAction { return; } } - final AppEngineUploader uploader = AppEngineUploader.createUploader(project, artifact); + final AppEngineUploader uploader = AppEngineUploader.createUploader(project, artifact, null); if (uploader != null) { uploader.startUploading(); } diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java new file mode 100644 index 000000000000..d90d1f20b103 --- /dev/null +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java @@ -0,0 +1,147 @@ +/* + * Copyright 2000-2013 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.appengine.cloud; + +import com.intellij.appengine.actions.AppEngineUploader; +import com.intellij.appengine.util.AppEngineUtil; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.UnnamedConfigurable; +import com.intellij.openapi.project.Project; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactPointerManager; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.deployment.ArtifactDeploymentSource; +import com.intellij.remoteServer.deployment.Deployer; +import com.intellij.remoteServer.deployment.DeploymentSource; +import com.intellij.remoteServer.deployment.DeploymentSourceUtil; +import com.intellij.util.ui.FormBuilder; +import icons.GoogleAppEngineIcons; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class AppEngineCloudType extends ServerType { + + public AppEngineCloudType() { + super("google-app-engine"); + } + + @NotNull + @Override + public String getPresentableName() { + return "Google App Engine"; + } + + @NotNull + @Override + public Icon getIcon() { + return GoogleAppEngineIcons.AppEngine; + } + + @NotNull + @Override + public AppEngineServerConfiguration createDefaultConfiguration() { + return new AppEngineServerConfiguration(); + } + + @NotNull + @Override + public UnnamedConfigurable createConfigurable(@NotNull AppEngineServerConfiguration configuration) { + return new AppEngineCloudConfigurable(configuration); + } + + @NotNull + @Override + public Deployer createDeployer(Project project) { + return new AppEngineDeployer(project); + } + + private static class AppEngineCloudConfigurable implements UnnamedConfigurable { + private final JTextField myEmailField; + private final AppEngineServerConfiguration myConfiguration; + + public AppEngineCloudConfigurable(AppEngineServerConfiguration configuration) { + myConfiguration = configuration; + myEmailField = new JTextField(); + myEmailField.setPreferredSize(new Dimension(250, myEmailField.getPreferredSize().height)); + } + + @Nullable + @Override + public JComponent createComponent() { + return FormBuilder.createFormBuilder().addLabeledComponent("E-mail:", myEmailField).getPanel(); + } + + @Override + public boolean isModified() { + return !myEmailField.getText().equals(myConfiguration.getEmail()); + } + + @Override + public void apply() throws ConfigurationException { + myConfiguration.setEmail(myEmailField.getText()); + } + + @Override + public void reset() { + myEmailField.setText(myConfiguration.getEmail()); + } + + @Override + public void disposeUIResources() { + } + } + + private static class AppEngineDeployer extends Deployer { + private final Project myProject; + + public AppEngineDeployer(Project project) { + myProject = project; + } + + @NotNull + @Override + public List getAvailableDeploymentSources() { + List artifacts = AppEngineUtil.collectWebArtifacts(myProject, true); + List sources = new ArrayList(); + ArtifactPointerManager pointerManager = ArtifactPointerManager.getInstance(myProject); + for (Artifact artifact : artifacts) { + sources.add(DeploymentSourceUtil.getInstance().createArtifactDeploymentSource(pointerManager.createPointer(artifact))); + } + return sources; + } + + @Override + public void startDeployment(@NotNull RemoteServer server, + @NotNull DeploymentSource source) { + Artifact artifact = ((ArtifactDeploymentSource)source).getArtifact(); + if (artifact == null) return; + + AppEngineUploader uploader = AppEngineUploader.createUploader(myProject, artifact, server.getConfiguration()); + if (uploader != null) { + uploader.startUploading(); + } + } + } +} diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineServerConfiguration.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineServerConfiguration.java new file mode 100644 index 000000000000..9291f376fc7d --- /dev/null +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineServerConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2013 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.appengine.cloud; + +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.remoteServer.configuration.ServerConfiguration; +import com.intellij.util.xmlb.XmlSerializerUtil; +import com.intellij.util.xmlb.annotations.Attribute; +import org.jetbrains.annotations.Nullable; + +/** + * @author nik + */ +public class AppEngineServerConfiguration extends ServerConfiguration implements PersistentStateComponent { + private String myEmail; + + @Attribute("email") + public String getEmail() { + return myEmail; + } + + public void setEmail(String email) { + myEmail = email; + } + + @Nullable + @Override + public AppEngineServerConfiguration getState() { + return this; + } + + @Override + public void loadState(AppEngineServerConfiguration state) { + XmlSerializerUtil.copyBean(state, this); + } + + @Override + public PersistentStateComponent getSerializer() { + return this; + } +} diff --git a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java index df9222554dcc..3e4cda649855 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/facet/AppEngineAccountDialog.java @@ -16,6 +16,7 @@ package com.intellij.appengine.facet; import com.intellij.CommonBundle; +import com.intellij.appengine.cloud.AppEngineServerConfiguration; import com.intellij.ide.passwordSafe.PasswordSafe; import com.intellij.ide.passwordSafe.PasswordSafeException; import com.intellij.ide.util.PropertiesComponent; @@ -39,12 +40,14 @@ public class AppEngineAccountDialog extends DialogWrapper { private JPasswordField myPasswordField; private JTextField myUserEmailField; private final Project myProject; + @Nullable private final AppEngineServerConfiguration myConfiguration; - public AppEngineAccountDialog(@NotNull Project project) { + public AppEngineAccountDialog(@NotNull Project project, @Nullable AppEngineServerConfiguration configuration) { super(project); myProject = project; + myConfiguration = configuration; setTitle("AppEngine Account"); - myUserEmailField.setText(StringUtil.notNullize(getStoredEmail(project))); + myUserEmailField.setText(StringUtil.notNullize(getStoredEmail(myConfiguration, project))); init(); } @@ -67,14 +70,22 @@ public class AppEngineAccountDialog extends DialogWrapper { } @Nullable - public static String getStoredEmail(@NotNull Project project) { - return PropertiesComponent.getInstance(project).getValue(EMAIL_KEY); + public static String getStoredEmail(@Nullable AppEngineServerConfiguration configuration, @NotNull Project project) { + if (configuration != null) { + return configuration.getEmail(); + } + return PropertiesComponent.getInstance(project).getValue(EMAIL_KEY);//todo[nik] remove this } @Override protected void doOKAction() { final String email = getEmail(); - PropertiesComponent.getInstance(myProject).setValue(EMAIL_KEY, email); + if (myConfiguration != null) { + myConfiguration.setEmail(email); + } + else { + PropertiesComponent.getInstance(myProject).setValue(EMAIL_KEY, email); + } if (myRememberPasswordCheckBox.isSelected()) { try { PasswordSafe.getInstance().storePassword(myProject, AppEngineAccountDialog.class, getPasswordKey(email), getPassword()); diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml index a2c79d736efb..dcb2acda4d18 100644 --- a/resources/src/idea/RichPlatformPlugin.xml +++ b/resources/src/idea/RichPlatformPlugin.xml @@ -385,6 +385,7 @@ +