extract interfaces to improve testability
[teamcity/dotNetPackagesSupport.git] / nuget-server / src / jetbrains / buildServer / nuget / server / feed / reader / impl / PackagesFeedParserImpl.java
1 /*\r
2  * Copyright 2000-2011 JetBrains s.r.o.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
18 \r
19 import com.intellij.openapi.diagnostic.Logger;\r
20 import jetbrains.buildServer.nuget.common.PackageInfo;\r
21 import jetbrains.buildServer.nuget.server.feed.reader.FeedPackage;\r
22 import jetbrains.buildServer.util.StringUtil;\r
23 import org.jdom.Element;\r
24 import org.jdom.Namespace;\r
25 import org.jetbrains.annotations.NotNull;\r
26 \r
27 import java.util.ArrayList;\r
28 import java.util.Collection;\r
29 import java.util.Collections;\r
30 import java.util.List;\r
31 \r
32 /**\r
33  * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
34  * Date: 12.08.11 13:42\r
35  */\r
36 public class PackagesFeedParserImpl implements PackagesFeedParser {\r
37   private static final Logger LOG = Logger.getInstance(PackagesFeedParserImpl.class.getName());\r
38 \r
39   private static final Namespace atom = Namespace.getNamespace("http://www.w3.org/2005/Atom");\r
40   private static final Namespace metadata = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");\r
41   private static final Namespace services = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices");\r
42 \r
43   public Collection<FeedPackage> readPackages(@NotNull Element root) {\r
44     final List<FeedPackage> result = new ArrayList<FeedPackage>();\r
45 \r
46     final List entries = root.getChildren("entry", atom);\r
47     for (Object o : entries) {\r
48       final Element entry = (Element) o;\r
49       try {\r
50         final FeedPackage e = parseOneEntry(entry);\r
51         result.add(e);\r
52       } catch (InvalidXmlException e) {\r
53         LOG.debug("Failed to parse feed entry. " + e.getMessage());\r
54       }\r
55     }\r
56     Collections.sort(result);\r
57     return result;\r
58   }\r
59 \r
60   @NotNull\r
61   private FeedPackage parseOneEntry(Element entry) throws InvalidXmlException {\r
62     final Element atomIdElement = getChild(entry, "id", atom);\r
63     final String atomId = atomIdElement.getText();\r
64 \r
65     final String content = getChildAttribute(entry, "content", atom, "src");\r
66     final Element props = getChild(entry, "properties", metadata);\r
67 \r
68     final String packageId = getChildText(props, "Id", services);\r
69     final String version = getChildText(props, "Version", services);\r
70     final String desription = getChildText(props, "Description", services);\r
71     final String summary = getChildText(props, "Summary", services);\r
72     final boolean isLatestVersion = "true".equalsIgnoreCase(getChildTextSafe(props, "IsLatestVersion", services));\r
73 \r
74     return new FeedPackage(\r
75             atomId,\r
76             new PackageInfo(packageId, version),\r
77             isLatestVersion,\r
78             StringUtil.isEmptyOrSpaces(desription) ? summary : desription,\r
79             content);\r
80   }\r
81 \r
82   @NotNull\r
83   private String getChildTextSafe(@NotNull Element element,\r
84                                   @NotNull String name,\r
85                                   @NotNull Namespace ns) {\r
86     try {\r
87       return getChildText(element, name, ns);\r
88     } catch (InvalidXmlException e) {\r
89       return "";\r
90     }\r
91   }\r
92 \r
93   @NotNull\r
94   private String getChildText(@NotNull Element element,\r
95                               @NotNull String name,\r
96                               @NotNull Namespace ns) throws InvalidXmlException {\r
97     final Element data = getChild(element, name, ns);\r
98     final String text = data.getText();\r
99     if (StringUtil.isEmptyOrSpaces(text)) {\r
100       throw new InvalidXmlException("Element " + name + " must have a content. ");\r
101     }\r
102     return text;\r
103   }\r
104 \r
105   @NotNull\r
106   private String getChildAttribute(@NotNull Element element,\r
107                                    @NotNull String name,\r
108                                    @NotNull Namespace ns,\r
109                                    @NotNull String attribute) throws InvalidXmlException {\r
110     final Element data = getChild(element, name, ns);\r
111     final String text = data.getAttributeValue(attribute);\r
112     if (StringUtil.isEmptyOrSpaces(text)) {\r
113       throw new InvalidXmlException("Element " + name + " must have non-empty attribute " + attribute + ". ");\r
114     }\r
115     return text;\r
116   }\r
117 \r
118   @NotNull\r
119   private Element getChild(Element element, String name, Namespace ns) throws InvalidXmlException {\r
120     final Element data = element.getChild(name, ns);\r
121     if (data == null) {\r
122       throw new InvalidXmlException("Element " + name + " was not found. ");\r
123     }\r
124     return data;\r
125   }\r
126 \r
127   private static class InvalidXmlException extends Exception {\r
128     private InvalidXmlException(String message) {\r
129       super(message);\r
130     }\r
131   }\r
132 }\r