1 // Copyright 2011 Google Inc. All Rights Reserved.
2 package com
.google
.apphosting
.utils
.config
;
4 import org
.mortbay
.xml
.XmlParser
;
6 import java
.io
.InputStream
;
7 import java
.util
.EnumSet
;
8 import java
.util
.Iterator
;
11 * Creates a {@link BackendsXml} instance from
12 * <appdir>WEB-INF/backends.xml. If you want to read the
13 * configuration from a different file, subclass and override
14 * {@link #getFilename()}. If you want to read the configuration from
15 * something that isn't a file, subclass and override
16 * {@link #getInputStream()}.
19 public class BackendsXmlReader
extends AbstractConfigXmlReader
<BackendsXml
> {
21 private static final String FILENAME
= "WEB-INF/backends.xml";
24 * Constructs the reader for {@code backends.xml} in a given application directory.
25 * @param appDir the application directory
27 public BackendsXmlReader(String appDir
) {
32 * Parses the config file.
33 * @return A {@link BackendsXml} object representing the parsed configuration.
35 public BackendsXml
readBackendsXml() {
36 return readConfigXml();
40 protected BackendsXml
processXml(InputStream is
) {
41 BackendsXml backendsXml
= new BackendsXml();
43 XmlParser
.Node rootNode
= getTopLevelNode(is
);
44 Iterator
<?
> backends
= rootNode
.iterator("backend");
45 while (backends
.hasNext()) {
46 XmlParser
.Node node
= (XmlParser
.Node
) backends
.next();
47 backendsXml
.addBackend(convertBackendNode(node
));
54 protected String
getRelativeFilename() {
58 private BackendsXml
.Entry
convertBackendNode(XmlParser
.Node node
) {
59 String name
= trim(node
.getAttribute("name"));
60 Integer instances
= null;
61 String instanceClass
= node
.getString("class", false, true);
62 Integer maxConcurrentRequests
= null;
63 EnumSet
<BackendsXml
.Option
> options
= EnumSet
.noneOf(BackendsXml
.Option
.class);
65 XmlParser
.Node subNode
= node
.get("instances");
66 if (subNode
!= null) {
67 instances
= Integer
.valueOf(getTextNode(subNode
));
71 XmlParser
.Node subNode
= node
.get("max-concurrent-requests");
72 if (subNode
!= null) {
73 maxConcurrentRequests
= Integer
.valueOf(getTextNode(subNode
));
77 XmlParser
.Node subNode
= node
.get("options");
78 if (subNode
!= null) {
79 XmlParser
.Node failFastNode
= subNode
.get("fail-fast");
80 if (failFastNode
!= null) {
81 if (getBooleanValue(failFastNode
)) {
82 options
.add(BackendsXml
.Option
.FAIL_FAST
);
85 XmlParser
.Node dynamicNode
= subNode
.get("dynamic");
86 if (dynamicNode
!= null) {
87 if (getBooleanValue(dynamicNode
)) {
88 options
.add(BackendsXml
.Option
.DYNAMIC
);
91 XmlParser
.Node publicNode
= subNode
.get("public");
92 if (publicNode
!= null) {
93 if (getBooleanValue(publicNode
)) {
94 options
.add(BackendsXml
.Option
.PUBLIC
);
99 return new BackendsXml
.Entry(name
, instances
, instanceClass
,
100 maxConcurrentRequests
, options
, null);
103 private boolean getBooleanValue(XmlParser
.Node node
) {
104 String value
= getTextNode(node
);
105 value
= value
.trim();
106 return (value
.equalsIgnoreCase("true") || value
.equals("1"));
109 private String
getTextNode(XmlParser
.Node node
) {
110 String value
= (String
) node
.get(0);
117 private String
trim(String attribute
) {
118 return attribute
== null ?
null : attribute
.trim();