1.9.30 sync.
[gae.git] / java / src / main / com / google / apphosting / utils / config / AppEngineWebXmlReader.java
blobe4a394bfc7c035123b134c91a51e25b5080f0075
1 // Copyright 2008 Google Inc. All Rights Reserved.
2 package com.google.apphosting.utils.config;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.util.logging.Level;
10 import java.util.logging.Logger;
12 /**
13 * Creates an {@link AppEngineWebXml} instance from
14 * <appdir>WEB-INF/appengine-web.xml. If you want to read the configuration
15 * from something that isn't a file, subclass and override
16 * {@link #getInputStream()}.
19 public class AppEngineWebXmlReader {
20 private static final Logger logger =
21 Logger.getLogger(AppEngineWebXmlReader.class.getName());
23 private static final String CONCURRENT_REQUESTS_URL =
24 "http://code.google.com/appengine/docs/java/config/appconfig.html#Using_Concurrent_Requests";
26 private static final String DATASTORE_AUTO_IDS_URL =
27 "http://developers.google.com/appengine/docs/java/datastore/entities#Kinds_and_Identifiers";
29 private static final String APPCFG_AUTO_IDS_URL =
30 "http://developers.google.com/appengine/docs/java/config/appconfig#auto_id_policy";
32 public static final String DEFAULT_RELATIVE_FILENAME = "WEB-INF/appengine-web.xml";
34 private final String filename;
36 /**
37 * Creates a reader for appengine-web.xml.
39 * @param appDir The directory in which the config file resides.
40 * @param relativeFilename The path to the config file, relative to
41 * {@code appDir}.
43 public AppEngineWebXmlReader(String appDir, String relativeFilename) {
44 if (appDir.length() > 0 && appDir.charAt(appDir.length() - 1) != File.separatorChar) {
45 appDir += File.separatorChar;
47 this.filename = appDir + relativeFilename;
50 /**
51 * Creates a reader for appengine-web.xml.
53 * @param appDir The directory in which the config file resides. The
54 * path to the config file relative to the directory is assumed to be
55 * {@link #DEFAULT_RELATIVE_FILENAME}.
57 public AppEngineWebXmlReader(String appDir) {
58 this(appDir, DEFAULT_RELATIVE_FILENAME);
61 /**
62 * @return A {@link AppEngineWebXml} config object derived from the
63 * contents of <appdir>WEB-INF/appengine-web.xml.
65 * @throws AppEngineConfigException If <appdir>WEB-INF/appengine-web.xml does
66 * not exist. Also thrown if we are unable to parse the xml.
68 public AppEngineWebXml readAppEngineWebXml() {
69 InputStream is = null;
70 AppEngineWebXml appEngineWebXml;
71 try {
72 is = getInputStream();
73 appEngineWebXml = processXml(is);
74 logger.fine("Successfully processed " + getFilename());
75 if (!appEngineWebXml.getThreadsafeValueProvided()) {
76 if (allowMissingThreadsafeElement()) {
77 logger.warning("appengine-web.xml does not contain a <threadsafe> element. This will "
78 + "be treated as an error the next time you deploy.\nSee " + CONCURRENT_REQUESTS_URL
79 + " for more information.\nYou probably want to enable concurrent requests.");
80 } else {
81 throw new AppEngineConfigException("appengine-web.xml does not contain a <threadsafe> "
82 + "element.\nSee " + CONCURRENT_REQUESTS_URL + " for more information.\nYou probably "
83 + "want to enable concurrent requests.");
86 if ("legacy".equals(appEngineWebXml.getAutoIdPolicy())) {
87 logger.warning("You have set the datastore auto id policy to 'legacy'. It is recommended "
88 + "that you select 'default' instead.\nLegacy auto ids are deprecated. You can "
89 + "continue to allocate legacy ids manually using the allocateIds() API functions.\n"
90 + "For more information see:\n"
91 + APPCFG_AUTO_IDS_URL + "\n" + DATASTORE_AUTO_IDS_URL + "\n");
93 } catch (Exception e) {
94 String msg = "Received exception processing " + getFilename();
95 logger.log(Level.SEVERE, msg, e);
96 if (e instanceof AppEngineConfigException) {
97 throw (AppEngineConfigException) e;
99 throw new AppEngineConfigException(msg, e);
100 } finally {
101 close(is);
103 return appEngineWebXml;
106 protected boolean allowMissingThreadsafeElement() {
107 return false;
110 public String getFilename() {
111 return filename;
114 private void close(InputStream is) {
115 if (is != null) {
116 try {
117 is.close();
118 } catch (IOException e) {
119 throw new AppEngineConfigException(e);
124 protected AppEngineWebXml processXml(InputStream is) {
125 return new AppEngineWebXmlProcessor().processXml(is);
128 protected InputStream getInputStream() {
129 try {
130 return new FileInputStream(getFilename());
131 } catch (FileNotFoundException fnfe) {
132 throw new AppEngineConfigException(
133 "Could not locate " + new File(getFilename()).getAbsolutePath(), fnfe);