App Engine 1.8.4.
[gae.git] / java / src / main / com / google / apphosting / utils / config / CronXmlReader.java
blob6833f55cc199385b1aa8f0137a3f3f8ee0cb9b54
1 // Copyright 2008 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 CronXml} instance from
11 * <appdir>WEB-INF/cron.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 CronXmlReader extends AbstractConfigXmlReader<CronXml> {
19 private static final String FILENAME = "WEB-INF/cron.xml";
21 private static final String CRONENTRIES_TAG = "cronentries";
22 private static final String CRON_TAG = "cron";
23 private static final String DESCRIPTION_TAG = "description";
24 private static final String SCHEDULE_TAG = "schedule";
25 private static final String TARGET_TAG = "target";
26 private static final String TIMEZONE_TAG = "timezone";
27 private static final String URL_TAG = "url";
29 /**
30 * Constructs the reader for {@code cron.xml} in a given application directory.
31 * @param appDir the application directory
33 public CronXmlReader(String appDir) {
34 super(appDir, false);
37 /**
38 * Parses the config file.
39 * @return A {@link CronXml} object representing the parsed configuration.
41 public CronXml readCronXml() {
42 return readConfigXml();
45 @Override
46 protected CronXml processXml(InputStream is) {
47 final CronXml cronXml = new CronXml();
48 parse(new ParserCallback() {
49 boolean first = true;
50 CronXml.Entry entry;
52 @Override
53 public void newNode(Node node, Stack<Node> ancestors) {
54 switch (ancestors.size()) {
55 case 0:
56 if (!CRONENTRIES_TAG.equalsIgnoreCase(node.getTag())) {
57 throw new AppEngineConfigException(getFilename() + " does not contain <"
58 + CRONENTRIES_TAG + ">");
60 if (!first) {
61 throw new AppEngineConfigException(getFilename() + " contains multiple <"
62 + CRONENTRIES_TAG + ">");
64 first = false;
65 break;
67 case 1:
68 if (CRON_TAG.equalsIgnoreCase(node.getTag())) {
69 entry = cronXml.addNewEntry();
70 } else {
71 throw new AppEngineConfigException(getFilename() + " contains <"
72 + node.getTag() + "> instead of <" + CRON_TAG + "/>");
74 break;
76 case 2:
77 assert(entry != null);
78 if (DESCRIPTION_TAG.equalsIgnoreCase(node.getTag())) {
79 if (node.size() == 1 && node.get(0) instanceof String) {
80 entry.setDescription((String) node.get(0));
81 } else {
82 throw new AppEngineConfigException(getFilename() + " has bad contents in <"
83 + DESCRIPTION_TAG + ">");
85 } else if (URL_TAG.equalsIgnoreCase(node.getTag())) {
86 if (node.size() == 1 && node.get(0) instanceof String) {
87 entry.setUrl((String) node.get(0));
88 } else {
89 throw new AppEngineConfigException(getFilename() + " has bad contents in <"
90 + URL_TAG + ">");
92 } else if (SCHEDULE_TAG.equalsIgnoreCase(node.getTag())) {
93 if (node.size() == 1 && node.get(0) instanceof String) {
94 entry.setSchedule((String) node.get(0));
95 } else {
96 throw new AppEngineConfigException(getFilename() + " has bad contents in <"
97 + SCHEDULE_TAG + ">");
99 } else if (TIMEZONE_TAG.equalsIgnoreCase(node.getTag())) {
100 if (node.size() == 1 && node.get(0) instanceof String) {
101 entry.setTimezone((String) node.get(0));
102 } else {
103 throw new AppEngineConfigException(getFilename() + " has bad contents in <"
104 + TIMEZONE_TAG + ">");
106 } else if (TARGET_TAG.equalsIgnoreCase(node.getTag())) {
107 if (node.size() == 1 && node.get(0) instanceof String) {
108 entry.setTarget((String) node.get(0));
109 } else {
110 throw new AppEngineConfigException(getFilename() + " has bad contents in <"
111 + TARGET_TAG + ">");
113 } else {
114 throw new AppEngineConfigException(getFilename() + " contains unknown <"
115 + node.getTag() + "> inside <" + CRON_TAG + "/>");
117 break;
119 default:
120 throw new AppEngineConfigException(getFilename()
121 + " has a syntax error; node <"
122 + node.getTag() + "> is too deeply nested to be valid.");
125 }, is);
126 cronXml.validateLastEntry();
127 return cronXml;
130 @Override
131 protected String getRelativeFilename() {
132 return FILENAME;