App Engine Python SDK version 1.8.4
[gae.git] / java / src / main / com / google / apphosting / utils / config / DosXmlReader.java
blobe0069c0c6018e009dc7857780cb3c62b523f6291
1 // Copyright 2010 Google Inc. All Rights Reserved.
2 package com.google.apphosting.utils.config;
4 import org.mortbay.xml.XmlParser.Node;
6 import java.io.InputStream;
7 import java.util.Stack;
9 /**
10 * Creates an {@link DosXml} instance from
11 * <appdir>WEB-INF/dos.xml. If you want to read the configuration
12 * from a different file, subclass and override {@link #getFilename()}. If you
13 * want to read the configuration from something that isn't a file, subclass
14 * and override {@link #getInputStream()}.
17 public class DosXmlReader extends AbstractConfigXmlReader<DosXml> {
19 private static final String FILENAME = "WEB-INF/dos.xml";
21 private static final String BLACKLISTENTRIES_TAG = "blacklistentries";
22 private static final String BLACKLIST_TAG = "blacklist";
23 private static final String DESCRIPTION_TAG = "description";
24 private static final String SUBNET_TAG = "subnet";
26 /**
27 * Constructs the reader for {@code dos.xml} in a given application directory.
28 * @param appDir the application directory
30 public DosXmlReader(String appDir) {
31 super(appDir, false);
34 /**
35 * Parses the config file.
36 * @return A {@link DosXml} object representing the parsed configuration.
38 public DosXml readDosXml() {
39 return readConfigXml();
42 @Override
43 protected DosXml processXml(InputStream is) {
44 final DosXml dosXml = new DosXml();
45 parse(new ParserCallback() {
46 boolean first = true;
47 DosXml.BlacklistEntry blacklistEntry;
49 @Override
50 public void newNode(Node node, Stack<Node> ancestors) {
51 switch (ancestors.size()) {
52 case 0:
53 if (!BLACKLISTENTRIES_TAG.equalsIgnoreCase(node.getTag())) {
54 throw new AppEngineConfigException(getFilename() + " does not contain <"
55 + BLACKLISTENTRIES_TAG + ">");
57 if (!first) {
58 throw new AppEngineConfigException(getFilename() + " contains multiple <"
59 + BLACKLISTENTRIES_TAG + ">");
61 first = false;
62 break;
64 case 1:
65 if (BLACKLIST_TAG.equalsIgnoreCase(node.getTag())) {
66 blacklistEntry = dosXml.addNewBlacklistEntry();
67 } else {
68 throw new AppEngineConfigException(getFilename() + " contains <"
69 + node.getTag() + "> instead of <" + BLACKLIST_TAG + "/>");
71 break;
73 case 2:
74 assert(blacklistEntry != null);
75 if (DESCRIPTION_TAG.equalsIgnoreCase(node.getTag())) {
76 if (node.size() == 1 && node.get(0) instanceof String) {
77 blacklistEntry.setDescription((String) node.get(0));
78 } else {
79 throw new AppEngineConfigException(getFilename() + " has bad contents in <"
80 + DESCRIPTION_TAG + ">");
82 } else if (SUBNET_TAG.equalsIgnoreCase(node.getTag())) {
83 if (node.size() == 1 && node.get(0) instanceof String) {
84 blacklistEntry.setSubnet((String) node.get(0));
85 } else {
86 throw new AppEngineConfigException(getFilename() + " has bad contents in <"
87 + SUBNET_TAG + ">");
89 } else {
90 throw new AppEngineConfigException(getFilename() + " contains unknown <"
91 + node.getTag() + "> inside <" + BLACKLIST_TAG + "/>");
93 break;
95 default:
96 throw new AppEngineConfigException(getFilename()
97 + " has a syntax error; node <"
98 + node.getTag() + "> is too deeply nested to be valid.");
101 }, is);
102 dosXml.validateLastEntry();
103 return dosXml;
106 @Override
107 protected String getRelativeFilename() {
108 return FILENAME;