implement feed xml parser + tests
[teamcity/dotNetPackagesSupport.git] / nuget-server / src / jetbrains / buildServer / nuget / server / feed / reader / PackagesFeedParser.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;\r
18 \r
19 import com.intellij.openapi.diagnostic.Logger;\r
20 import jetbrains.buildServer.nuget.common.PackageInfo;\r
21 import jetbrains.buildServer.util.StringUtil;\r
22 import org.jdom.Element;\r
23 import org.jdom.Namespace;\r
24 import org.jetbrains.annotations.NotNull;\r
25 \r
26 import java.util.ArrayList;\r
27 import java.util.Collection;\r
28 import java.util.Collections;\r
29 import java.util.List;\r
30 \r
31 /**\r
32  * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
33  * Date: 12.08.11 13:42\r
34  */\r
35 public class PackagesFeedParser {\r
36   private static final Logger LOG = Logger.getInstance(PackagesFeedParser.class.getName());\r
37 \r
38   private static final Namespace atom = Namespace.getNamespace("http://www.w3.org/2005/Atom");\r
39   private static final Namespace metadata = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");\r
40   private static final Namespace services = Namespace.getNamespace("http://schemas.microsoft.com/ado/2007/08/dataservices");\r
41 \r
42   public Collection<FeedPackage> readPackages(@NotNull Element root) {\r
43     final List<FeedPackage> result = new ArrayList<FeedPackage>();\r
44 \r
45     final List entries = root.getChildren("entry", atom);\r
46     for (Object o : entries) {\r
47       final Element entry = (Element) o;\r
48       try {\r
49         final FeedPackage e = parseOneEntry(entry);\r
50         result.add(e);\r
51       } catch (InvalidXmlException e) {\r
52         LOG.debug("Failed to parse feed entry. " + e.getMessage());\r
53       }\r
54     }\r
55     Collections.sort(result);\r
56     return result;\r
57   }\r
58 \r
59   @NotNull\r
60   private FeedPackage parseOneEntry(Element entry) throws InvalidXmlException {\r
61     final Element atomIdElement = getChild(entry, "id", atom);\r
62     final String atomId = atomIdElement.getText();\r
63 \r
64     final String content = getChildAttribute(entry, "content", atom, "src");\r
65     final Element props = getChild(entry, "properties", metadata);\r
66 \r
67     final String packageId = getChildText(props, "Id", services);\r
68     final String version = getChildText(props, "Version", services);\r
69     final String desription = getChildText(props, "Description", services);\r
70     final String summary = getChildText(props, "Summary", services);\r
71     final boolean isLatestVersion = "true".equalsIgnoreCase(getChildTextSafe(props, "IsLatestVersion", services));\r
72 \r
73     return new FeedPackage(\r
74             atomId,\r
75             new PackageInfo(packageId, version),\r
76             isLatestVersion,\r
77             StringUtil.isEmptyOrSpaces(desription) ? summary : desription,\r
78             content);\r
79   }\r
80 \r
81   @NotNull\r
82   private String getChildTextSafe(@NotNull Element element,\r
83                                   @NotNull String name,\r
84                                   @NotNull Namespace ns) {\r
85     try {\r
86       return getChildText(element, name, ns);\r
87     } catch (InvalidXmlException e) {\r
88       return "";\r
89     }\r
90   }\r
91 \r
92   @NotNull\r
93   private String getChildText(@NotNull Element element,\r
94                               @NotNull String name,\r
95                               @NotNull Namespace ns) throws InvalidXmlException {\r
96     final Element data = getChild(element, name, ns);\r
97     final String text = data.getText();\r
98     if (StringUtil.isEmptyOrSpaces(text)) {\r
99       throw new InvalidXmlException("Element " + name + " must have a content. ");\r
100     }\r
101     return text;\r
102   }\r
103 \r
104   @NotNull\r
105   private String getChildAttribute(@NotNull Element element,\r
106                                    @NotNull String name,\r
107                                    @NotNull Namespace ns,\r
108                                    @NotNull String attribute) throws InvalidXmlException {\r
109     final Element data = getChild(element, name, ns);\r
110     final String text = data.getAttributeValue(attribute);\r
111     if (StringUtil.isEmptyOrSpaces(text)) {\r
112       throw new InvalidXmlException("Element " + name + " must have non-empty attribute " + attribute + ". ");\r
113     }\r
114     return text;\r
115   }\r
116 \r
117   @NotNull\r
118   private Element getChild(Element element, String name, Namespace ns) throws InvalidXmlException {\r
119     final Element data = element.getChild(name, ns);\r
120     if (data == null) {\r
121       throw new InvalidXmlException("Element " + name + " was not found. ");\r
122     }\r
123     return data;\r
124   }\r
125 \r
126   private static class InvalidXmlException extends Exception {\r
127     private InvalidXmlException(String message) {\r
128       super(message);\r
129     }\r
130   }\r
131 }\r