1 // Copyright 2008 Google Inc. All Rights Reserved.
2 package com
.google
.apphosting
.utils
.config
;
4 import com
.google
.common
.base
.CharMatcher
;
5 import com
.google
.common
.collect
.Lists
;
6 import com
.google
.common
.collect
.Maps
;
8 import java
.security
.Permissions
;
9 import java
.security
.UnresolvedPermission
;
10 import java
.util
.ArrayList
;
11 import java
.util
.Collections
;
12 import java
.util
.LinkedHashMap
;
13 import java
.util
.LinkedHashSet
;
14 import java
.util
.List
;
16 import java
.util
.Objects
;
18 import java
.util
.regex
.Pattern
;
21 * Struct describing the config data that lives in WEB-INF/appengine-web.xml.
23 * Any additions to this class should also be made to the YAML
24 * version in AppYaml.java.
27 public class AppEngineWebXml
implements Cloneable
{
29 * Enumeration of supported scaling types.
31 public static enum ScalingType
{AUTOMATIC
, MANUAL
, BASIC
}
33 private final Map
<String
, String
> systemProperties
= Maps
.newHashMap();
35 private final Map
<String
, String
> betaSettings
= Maps
.newLinkedHashMap();
37 private final HealthCheck healthCheck
;
39 private final Resources resources
;
41 private final Network network
;
43 private final Map
<String
, String
> envVariables
= Maps
.newHashMap();
45 private final List
<UserPermission
> userPermissions
= new ArrayList
<UserPermission
>();
47 public static final String WARMUP_SERVICE
= "warmup";
49 public static final String URL_HANDLER_URLFETCH
= "urlfetch";
50 public static final String URL_HANDLER_NATIVE
= "native";
54 private String majorVersionId
;
56 private String module
;
57 private String service
;
58 private String instanceClass
;
60 private final AutomaticScaling automaticScaling
;
61 private final ManualScaling manualScaling
;
62 private final BasicScaling basicScaling
;
64 private String sourceLanguage
;
65 private boolean sslEnabled
= true;
66 private boolean useSessions
= false;
67 private boolean asyncSessionPersistence
= false;
68 private String asyncSessionPersistenceQueueName
;
70 private final List
<StaticFileInclude
> staticFileIncludes
;
71 private final List
<String
> staticFileExcludes
;
72 private final List
<String
> resourceFileIncludes
;
73 private final List
<String
> resourceFileExcludes
;
75 private Pattern staticIncludePattern
;
76 private Pattern staticExcludePattern
;
77 private Pattern resourceIncludePattern
;
78 private Pattern resourceExcludePattern
;
80 private String publicRoot
= "";
82 private String appRoot
;
84 private final Set
<String
> inboundServices
;
85 private boolean precompilationEnabled
= true;
87 private final List
<AdminConsolePage
> adminConsolePages
= new ArrayList
<AdminConsolePage
>();
88 private final List
<ErrorHandler
> errorHandlers
= new ArrayList
<ErrorHandler
>();
90 private ClassLoaderConfig classLoaderConfig
;
92 private String urlStreamHandlerType
= null;
94 private boolean threadsafe
= false;
95 private boolean threadsafeValueProvided
= false;
97 private String autoIdPolicy
;
99 private boolean codeLock
= false;
100 private boolean useVm
= false;
101 private String env
= "1";
102 private ApiConfig apiConfig
;
103 private final List
<String
> apiEndpointIds
;
104 private Pagespeed pagespeed
;
107 * Represent user's choice w.r.t the usage of Google's customized connector-j.
109 public static enum UseGoogleConnectorJ
{
114 private UseGoogleConnectorJ useGoogleConnectorJ
= UseGoogleConnectorJ
.NOT_STATED_BY_USER
;
116 public AppEngineWebXml() {
117 automaticScaling
= new AutomaticScaling();
118 manualScaling
= new ManualScaling();
119 basicScaling
= new BasicScaling();
120 healthCheck
= new HealthCheck();
121 resources
= new Resources();
122 network
= new Network();
124 staticFileIncludes
= new ArrayList
<StaticFileInclude
>();
125 staticFileExcludes
= new ArrayList
<String
>();
126 staticFileExcludes
.add("WEB-INF/**");
127 staticFileExcludes
.add("**.jsp");
128 resourceFileIncludes
= new ArrayList
<String
>();
129 resourceFileExcludes
= new ArrayList
<String
>();
130 inboundServices
= new LinkedHashSet
<String
>();
131 apiEndpointIds
= new ArrayList
<String
>();
134 public AppEngineWebXml
clone() {
136 return (AppEngineWebXml
) super.clone();
137 } catch (CloneNotSupportedException ce
) {
138 throw new RuntimeException("Could not clone AppEngineWebXml", ce
);
143 * @return An unmodifiable map whose entries correspond to the
144 * system properties defined in appengine-web.xml.
146 public Map
<String
, String
> getSystemProperties() {
147 return Collections
.unmodifiableMap(systemProperties
);
150 public void addSystemProperty(String key
, String value
) {
151 systemProperties
.put(key
, value
);
155 * @return An unmodifiable map whose entires correspond to the
156 * vm settings defined in appengine-web.xml.
158 public Map
<String
, String
> getBetaSettings() {
159 return Collections
.unmodifiableMap(betaSettings
);
162 public void addBetaSetting(String key
, String value
) {
163 betaSettings
.put(key
, value
);
166 public HealthCheck
getHealthCheck() {
170 public Resources
getResources() {
174 public Network
getNetwork() {
179 * @return An unmodifiable map whose entires correspond to the
180 * environment variables defined in appengine-web.xml.
182 public Map
<String
, String
> getEnvironmentVariables() {
183 return Collections
.unmodifiableMap(envVariables
);
186 public void addEnvironmentVariable(String key
, String value
) {
187 envVariables
.put(key
, value
);
190 public String
getAppId() {
194 public void setAppId(String appId
) {
198 public String
getMajorVersionId() {
199 return majorVersionId
;
202 public void setMajorVersionId(String majorVersionId
) {
203 this.majorVersionId
= majorVersionId
;
206 public String
getSourceLanguage() {
207 return this.sourceLanguage
;
210 public void setSourceLanguage(String sourceLanguage
) {
211 this.sourceLanguage
= sourceLanguage
;
214 public String
getModule() {
218 public String
getService() {
223 * Sets instanceClass (aka class in the xml/yaml files). Normalizes empty and null
226 public void setInstanceClass(String instanceClass
) {
227 this.instanceClass
= toNullIfEmptyOrWhitespace(instanceClass
);
230 public String
getInstanceClass() {
231 return instanceClass
;
234 public AutomaticScaling
getAutomaticScaling() {
235 return automaticScaling
;
238 public ManualScaling
getManualScaling() {
239 return manualScaling
;
242 public BasicScaling
getBasicScaling() {
246 public ScalingType
getScalingType() {
247 if (!getBasicScaling().isEmpty()) {
248 return ScalingType
.BASIC
;
249 } else if (!getManualScaling().isEmpty()) {
250 return ScalingType
.MANUAL
;
252 return ScalingType
.AUTOMATIC
;
256 public void setModule(String module
) {
257 this.module
= module
;
260 public void setService(String service
) {
261 this.service
= service
;
264 public void setSslEnabled(boolean ssl
) {
268 public boolean getSslEnabled() {
272 public void setSessionsEnabled(boolean sessions
) {
273 useSessions
= sessions
;
276 public boolean getSessionsEnabled() {
280 public void setAsyncSessionPersistence(boolean asyncSessionPersistence
) {
281 this.asyncSessionPersistence
= asyncSessionPersistence
;
284 public boolean getAsyncSessionPersistence() {
285 return asyncSessionPersistence
;
288 public void setAsyncSessionPersistenceQueueName(String asyncSessionPersistenceQueueName
) {
289 this.asyncSessionPersistenceQueueName
= asyncSessionPersistenceQueueName
;
292 public String
getAsyncSessionPersistenceQueueName() {
293 return asyncSessionPersistenceQueueName
;
296 public List
<StaticFileInclude
> getStaticFileIncludes() {
297 return staticFileIncludes
;
300 public List
<String
> getStaticFileExcludes() {
301 return staticFileExcludes
;
304 public StaticFileInclude
includeStaticPattern(String pattern
, String expiration
) {
305 staticIncludePattern
= null;
306 StaticFileInclude staticFileInclude
= new StaticFileInclude(pattern
, expiration
);
307 staticFileIncludes
.add(staticFileInclude
);
308 return staticFileInclude
;
311 public void excludeStaticPattern(String url
) {
312 staticExcludePattern
= null;
313 staticFileExcludes
.add(url
);
316 public List
<String
> getResourcePatterns() {
317 return resourceFileIncludes
;
320 public List
<String
> getResourceFileExcludes() {
321 return resourceFileExcludes
;
324 public void includeResourcePattern(String url
) {
325 resourceExcludePattern
= null;
326 resourceFileIncludes
.add(url
);
329 public void excludeResourcePattern(String url
) {
330 resourceIncludePattern
= null;
331 resourceFileExcludes
.add(url
);
334 public void addUserPermission(String className
, String name
, String actions
) {
335 if (className
.startsWith("java.")) {
336 throw new AppEngineConfigException("Cannot specify user-permissions for " +
337 "classes in java.* packages.");
340 userPermissions
.add(new UserPermission(className
, name
, actions
));
343 public Permissions
getUserPermissions() {
344 Permissions permissions
= new Permissions();
345 for (UserPermission permission
: userPermissions
) {
346 permissions
.add(new UnresolvedPermission(permission
.getClassName(),
347 permission
.getName(),
348 permission
.getActions(),
351 permissions
.setReadOnly();
355 public void setPublicRoot(String root
) {
356 if (root
.indexOf('*') != -1) {
357 throw new AppEngineConfigException("public-root cannot contain wildcards");
359 if (root
.endsWith("/")) {
360 root
= root
.substring(0, root
.length() - 1);
362 if (root
.length() > 0 && !root
.startsWith("/")) {
365 staticIncludePattern
= null;
369 public String
getPublicRoot() {
373 public void addInboundService(String service
) {
374 inboundServices
.add(service
);
377 public Set
<String
> getInboundServices() {
378 return inboundServices
;
381 public boolean getPrecompilationEnabled() {
382 return precompilationEnabled
;
385 public void setPrecompilationEnabled(boolean precompilationEnabled
) {
386 this.precompilationEnabled
= precompilationEnabled
;
389 public boolean getWarmupRequestsEnabled() {
390 return inboundServices
.contains(WARMUP_SERVICE
);
393 public void setWarmupRequestsEnabled(boolean warmupRequestsEnabled
) {
394 if (warmupRequestsEnabled
) {
395 inboundServices
.add(WARMUP_SERVICE
);
397 inboundServices
.remove(WARMUP_SERVICE
);
401 public List
<AdminConsolePage
> getAdminConsolePages() {
402 return Collections
.unmodifiableList(adminConsolePages
);
405 public void addAdminConsolePage(AdminConsolePage page
) {
406 adminConsolePages
.add(page
);
409 public List
<ErrorHandler
> getErrorHandlers() {
410 return Collections
.unmodifiableList(errorHandlers
);
413 public void addErrorHandler(ErrorHandler handler
) {
414 errorHandlers
.add(handler
);
417 public boolean getThreadsafe() {
421 public boolean getThreadsafeValueProvided() {
422 return threadsafeValueProvided
;
425 public void setThreadsafe(boolean threadsafe
) {
426 this.threadsafe
= threadsafe
;
427 this.threadsafeValueProvided
= true;
430 public void setAutoIdPolicy(String policy
) {
431 autoIdPolicy
= policy
;
434 public String
getAutoIdPolicy() {
438 public boolean getCodeLock() {
442 public void setCodeLock(boolean codeLock
) {
443 this.codeLock
= codeLock
;
446 public void setUseVm(boolean useVm
) {
450 public boolean getUseVm() {
454 public void setEnv(String env
) {
458 public String
getEnv() {
462 public ApiConfig
getApiConfig() {
466 public void setApiConfig(ApiConfig config
) {
470 public ClassLoaderConfig
getClassLoaderConfig() {
471 return classLoaderConfig
;
474 public void setClassLoaderConfig(ClassLoaderConfig classLoaderConfig
) {
475 if (this.classLoaderConfig
!= null) {
476 throw new AppEngineConfigException("class-loader-config may only be specified once.");
478 this.classLoaderConfig
= classLoaderConfig
;
481 public String
getUrlStreamHandlerType() {
482 return urlStreamHandlerType
;
485 public void setUrlStreamHandlerType(String urlStreamHandlerType
) {
486 if (this.classLoaderConfig
!= null) {
487 throw new AppEngineConfigException("url-stream-handler may only be specified once.");
489 if (!URL_HANDLER_URLFETCH
.equals(urlStreamHandlerType
)
490 && !URL_HANDLER_NATIVE
.equals(urlStreamHandlerType
)) {
491 throw new AppEngineConfigException(
492 "url-stream-handler must be " + URL_HANDLER_URLFETCH
+ " or " + URL_HANDLER_NATIVE
+
493 " given " + urlStreamHandlerType
);
495 this.urlStreamHandlerType
= urlStreamHandlerType
;
499 * Returns true if {@code url} matches one of the servlets or servlet
500 * filters listed in this web.xml that has api-endpoint set to true.
502 public boolean isApiEndpoint(String id
) {
503 return apiEndpointIds
.contains(id
);
506 public void addApiEndpoint(String id
) {
507 apiEndpointIds
.add(id
);
510 public Pagespeed
getPagespeed() {
514 public void setPagespeed(Pagespeed pagespeed
) {
515 this.pagespeed
= pagespeed
;
518 public void setUseGoogleConnectorJ(boolean useGoogleConnectorJ
) {
519 if (useGoogleConnectorJ
) {
520 this.useGoogleConnectorJ
= UseGoogleConnectorJ
.TRUE
;
522 this.useGoogleConnectorJ
= UseGoogleConnectorJ
.FALSE
;
526 public UseGoogleConnectorJ
getUseGoogleConnectorJ() {
527 return useGoogleConnectorJ
;
531 public String
toString() {
532 return "AppEngineWebXml{"
533 + "systemProperties="
537 + ", userPermissions="
542 + ", majorVersionId='"
545 + ", sourceLanguage='"
551 + ", instanceClass='"
554 + ", automaticScaling="
570 + ", asyncSessionPersistence="
571 + asyncSessionPersistence
572 + ", asyncSessionPersistenceQueueName='"
573 + asyncSessionPersistenceQueueName
575 + ", staticFileIncludes="
577 + ", staticFileExcludes="
579 + ", resourceFileIncludes="
580 + resourceFileIncludes
581 + ", resourceFileExcludes="
582 + resourceFileExcludes
583 + ", staticIncludePattern="
584 + staticIncludePattern
585 + ", staticExcludePattern="
586 + staticExcludePattern
587 + ", resourceIncludePattern="
588 + resourceIncludePattern
589 + ", resourceExcludePattern="
590 + resourceExcludePattern
597 + ", inboundServices="
599 + ", precompilationEnabled="
600 + precompilationEnabled
601 + ", adminConsolePages="
607 + ", threadsafeValueProvided="
608 + threadsafeValueProvided
615 + ", apiEndpointIds="
619 + ", classLoaderConfig="
621 + ", urlStreamHandlerType="
622 + (urlStreamHandlerType
== null ? URL_HANDLER_URLFETCH
: urlStreamHandlerType
)
623 + ", useGoogleConnectorJ="
624 + useGoogleConnectorJ
629 public boolean equals(Object o
) {
633 if (o
== null || getClass() != o
.getClass()) {
637 AppEngineWebXml that
= (AppEngineWebXml
) o
;
639 if (asyncSessionPersistence
!= that
.asyncSessionPersistence
) {
642 if (precompilationEnabled
!= that
.precompilationEnabled
) {
645 if (sslEnabled
!= that
.sslEnabled
) {
648 if (threadsafe
!= that
.threadsafe
) {
651 if (threadsafeValueProvided
!= that
.threadsafeValueProvided
) {
654 if (autoIdPolicy
!= null ?
!autoIdPolicy
.equals(that
.autoIdPolicy
)
655 : that
.autoIdPolicy
!= null) {
658 if (codeLock
!= that
.codeLock
) {
661 if (useSessions
!= that
.useSessions
) {
664 if (adminConsolePages
!= null ?
!adminConsolePages
.equals(that
.adminConsolePages
)
665 : that
.adminConsolePages
!= null) {
668 if (appId
!= null ?
!appId
.equals(that
.appId
) : that
.appId
!= null) {
671 if (majorVersionId
!= null ?
!majorVersionId
.equals(that
.majorVersionId
)
672 : that
.majorVersionId
!= null) {
675 if (service
!= null ?
!service
.equals(that
.service
) : that
.service
!= null) {
678 if (instanceClass
!= null ?
!instanceClass
.equals(that
.instanceClass
)
679 : that
.instanceClass
!= null) {
682 if (!automaticScaling
.equals(that
.automaticScaling
)) {
685 if (!manualScaling
.equals(that
.manualScaling
)) {
688 if (!basicScaling
.equals(that
.basicScaling
)) {
691 if (appRoot
!= null ?
!appRoot
.equals(that
.appRoot
) : that
.appRoot
!= null) {
694 if (asyncSessionPersistenceQueueName
!= null ?
!asyncSessionPersistenceQueueName
695 .equals(that
.asyncSessionPersistenceQueueName
)
696 : that
.asyncSessionPersistenceQueueName
!= null) {
699 if (envVariables
!= null ?
!envVariables
.equals(that
.envVariables
)
700 : that
.envVariables
!= null) {
703 if (errorHandlers
!= null ?
!errorHandlers
.equals(that
.errorHandlers
)
704 : that
.errorHandlers
!= null) {
707 if (inboundServices
!= null ?
!inboundServices
.equals(that
.inboundServices
)
708 : that
.inboundServices
!= null) {
711 if (majorVersionId
!= null ?
!majorVersionId
.equals(that
.majorVersionId
)
712 : that
.majorVersionId
!= null) {
715 if (sourceLanguage
!= null ?
!sourceLanguage
.equals(that
.sourceLanguage
)
716 : that
.sourceLanguage
!= null) {
719 if (publicRoot
!= null ?
!publicRoot
.equals(that
.publicRoot
) : that
.publicRoot
!= null) {
722 if (resourceExcludePattern
!= null ?
!resourceExcludePattern
.equals(that
.resourceExcludePattern
)
723 : that
.resourceExcludePattern
!= null) {
726 if (resourceFileExcludes
!= null ?
!resourceFileExcludes
.equals(that
.resourceFileExcludes
)
727 : that
.resourceFileExcludes
!= null) {
730 if (resourceFileIncludes
!= null ?
!resourceFileIncludes
.equals(that
.resourceFileIncludes
)
731 : that
.resourceFileIncludes
!= null) {
734 if (resourceIncludePattern
!= null ?
!resourceIncludePattern
.equals(that
.resourceIncludePattern
)
735 : that
.resourceIncludePattern
!= null) {
738 if (staticExcludePattern
!= null ?
!staticExcludePattern
.equals(that
.staticExcludePattern
)
739 : that
.staticExcludePattern
!= null) {
742 if (staticFileExcludes
!= null ?
!staticFileExcludes
.equals(that
.staticFileExcludes
)
743 : that
.staticFileExcludes
!= null) {
746 if (staticFileIncludes
!= null ?
!staticFileIncludes
.equals(that
.staticFileIncludes
)
747 : that
.staticFileIncludes
!= null) {
750 if (staticIncludePattern
!= null ?
!staticIncludePattern
.equals(that
.staticIncludePattern
)
751 : that
.staticIncludePattern
!= null) {
754 if (systemProperties
!= null ?
!systemProperties
.equals(that
.systemProperties
)
755 : that
.systemProperties
!= null) {
758 if (betaSettings
!= null ?
!betaSettings
.equals(that
.betaSettings
) : that
.betaSettings
!= null) {
761 if (healthCheck
!= null ?
!healthCheck
.equals(that
.healthCheck
)
762 : that
.healthCheck
!= null) {
765 if (resources
!= null ?
!resources
.equals(that
.resources
) : that
.resources
!= null) {
768 if (network
!= null ?
!network
.equals(that
.network
) : that
.network
!= null) {
771 if (userPermissions
!= null ?
!userPermissions
.equals(that
.userPermissions
)
772 : that
.userPermissions
!= null) {
775 if (apiConfig
!= null ?
!apiConfig
.equals(that
.apiConfig
)
776 : that
.apiConfig
!= null) {
779 if (apiEndpointIds
!= null ?
!apiEndpointIds
.equals(that
.apiEndpointIds
)
780 : that
.apiEndpointIds
!= null) {
783 if (pagespeed
!= null ?
!pagespeed
.equals(that
.pagespeed
) : that
.pagespeed
!= null) {
786 if (classLoaderConfig
!= null ?
!classLoaderConfig
.equals(that
.classLoaderConfig
) :
787 that
.classLoaderConfig
!= null) {
790 if (urlStreamHandlerType
!= null ?
!urlStreamHandlerType
.equals(that
.urlStreamHandlerType
) :
791 that
.urlStreamHandlerType
!= null) {
794 if (useGoogleConnectorJ
!= that
.useGoogleConnectorJ
) {
802 public int hashCode() {
803 int result
= systemProperties
!= null ? systemProperties
.hashCode() : 0;
804 result
= 31 * result
+ (envVariables
!= null ? envVariables
.hashCode() : 0);
805 result
= 31 * result
+ (userPermissions
!= null ? userPermissions
.hashCode() : 0);
806 result
= 31 * result
+ (appId
!= null ? appId
.hashCode() : 0);
807 result
= 31 * result
+ (majorVersionId
!= null ? majorVersionId
.hashCode() : 0);
808 result
= 31 * result
+ (sourceLanguage
!= null ? sourceLanguage
.hashCode() : 0);
809 result
= 31 * result
+ (service
!= null ? service
.hashCode() : 0);
810 result
= 31 * result
+ (instanceClass
!= null ? instanceClass
.hashCode() : 0);
811 result
= 31 * result
+ automaticScaling
.hashCode();
812 result
= 31 * result
+ manualScaling
.hashCode();
813 result
= 31 * result
+ basicScaling
.hashCode();
814 result
= 31 * result
+ (sslEnabled ?
1 : 0);
815 result
= 31 * result
+ (useSessions ?
1 : 0);
816 result
= 31 * result
+ (asyncSessionPersistence ?
1 : 0);
818 31 * result
+ (asyncSessionPersistenceQueueName
!= null ? asyncSessionPersistenceQueueName
820 result
= 31 * result
+ (staticFileIncludes
!= null ? staticFileIncludes
.hashCode() : 0);
821 result
= 31 * result
+ (staticFileExcludes
!= null ? staticFileExcludes
.hashCode() : 0);
822 result
= 31 * result
+ (resourceFileIncludes
!= null ? resourceFileIncludes
.hashCode() : 0);
823 result
= 31 * result
+ (resourceFileExcludes
!= null ? resourceFileExcludes
.hashCode() : 0);
824 result
= 31 * result
+ (staticIncludePattern
!= null ? staticIncludePattern
.hashCode() : 0);
825 result
= 31 * result
+ (staticExcludePattern
!= null ? staticExcludePattern
.hashCode() : 0);
826 result
= 31 * result
+ (resourceIncludePattern
!= null ? resourceIncludePattern
.hashCode() : 0);
827 result
= 31 * result
+ (resourceExcludePattern
!= null ? resourceExcludePattern
.hashCode() : 0);
828 result
= 31 * result
+ (publicRoot
!= null ? publicRoot
.hashCode() : 0);
829 result
= 31 * result
+ (appRoot
!= null ? appRoot
.hashCode() : 0);
830 result
= 31 * result
+ (inboundServices
!= null ? inboundServices
.hashCode() : 0);
831 result
= 31 * result
+ (precompilationEnabled ?
1 : 0);
832 result
= 31 * result
+ (adminConsolePages
!= null ? adminConsolePages
.hashCode() : 0);
833 result
= 31 * result
+ (errorHandlers
!= null ? errorHandlers
.hashCode() : 0);
834 result
= 31 * result
+ (threadsafe ?
1 : 0);
835 result
= 31 * result
+ (autoIdPolicy
!= null ? autoIdPolicy
.hashCode() : 0);
836 result
= 31 * result
+ (threadsafeValueProvided ?
1 : 0);
837 result
= 31 * result
+ (codeLock ?
1 : 0);
838 result
= 31 * result
+ (apiConfig
!= null ? apiConfig
.hashCode() : 0);
839 result
= 31 * result
+ (apiEndpointIds
!= null ? apiEndpointIds
.hashCode() : 0);
840 result
= 31 * result
+ (pagespeed
!= null ? pagespeed
.hashCode() : 0);
841 result
= 31 * result
+ (classLoaderConfig
!= null ? classLoaderConfig
.hashCode() : 0);
842 result
= 31 * result
+ (urlStreamHandlerType
!= null ? urlStreamHandlerType
.hashCode() : 0);
843 result
= 31 * result
+ (useGoogleConnectorJ
.hashCode());
844 result
= 31 * result
+ (betaSettings
!= null ? betaSettings
.hashCode() : 0);
845 result
= 31 * result
+ (healthCheck
!= null ? healthCheck
.hashCode() : 0);
846 result
= 31 * result
+ (resources
!= null ? resources
.hashCode() : 0);
847 result
= 31 * result
+ (network
!= null ? network
.hashCode() : 0);
851 public boolean includesResource(String path
) {
852 if (resourceIncludePattern
== null) {
853 if (resourceFileIncludes
.size() == 0) {
854 resourceIncludePattern
= Pattern
.compile(".*");
856 resourceIncludePattern
= Pattern
.compile(makeRegexp(resourceFileIncludes
));
859 if (resourceExcludePattern
== null && resourceFileExcludes
.size() > 0) {
860 resourceExcludePattern
= Pattern
.compile(makeRegexp(resourceFileExcludes
));
863 return includes(path
, resourceIncludePattern
, resourceExcludePattern
);
866 public boolean includesStatic(String path
) {
867 if (staticIncludePattern
== null) {
868 if (staticFileIncludes
.size() == 0) {
870 if (publicRoot
.length() > 0) {
871 staticRoot
= publicRoot
+ "/**";
875 staticIncludePattern
= Pattern
.compile(
876 makeRegexp(Collections
.singletonList(staticRoot
)));
878 List
<String
> patterns
= new ArrayList
<String
>();
879 for (StaticFileInclude include
: staticFileIncludes
) {
880 patterns
.add(include
.getPattern());
882 staticIncludePattern
= Pattern
.compile(makeRegexp(patterns
));
885 if (staticExcludePattern
== null && staticFileExcludes
.size() > 0) {
886 staticExcludePattern
= Pattern
.compile(makeRegexp(staticFileExcludes
));
889 return includes(path
, staticIncludePattern
, staticExcludePattern
);
893 * Tests whether {@code path} is covered by the pattern {@code includes}
894 * while not being blocked by matching {@code excludes}.
896 * @param path a URL to test
897 * @param includes a non-{@code null} pattern for included URLs
898 * @param excludes a pattern for exclusion, or {@code null} to not exclude
899 * anything from the {@code includes} set.
901 public boolean includes(String path
, Pattern includes
, Pattern excludes
) {
902 assert(includes
!= null);
903 if (!includes
.matcher(path
).matches()) {
906 if (excludes
!= null && excludes
.matcher(path
).matches()) {
912 public String
makeRegexp(List
<String
> patterns
) {
913 StringBuilder builder
= new StringBuilder();
914 boolean first
= true;
915 for (String item
: patterns
) {
922 while (item
.charAt(0) == '/') {
923 item
= item
.substring(1);
927 if (appRoot
!= null) {
928 builder
.append(makeFileRegex(appRoot
));
931 builder
.append(makeFileRegex(item
));
934 return builder
.toString();
938 * Helper method to translate from appengine-web.xml "file globs" to
939 * proper regular expressions as used in app.yaml.
941 * @param fileGlob the glob to translate
942 * @return the regular expression string matching the input {@code file} pattern.
944 static String
makeFileRegex(String fileGlob
) {
945 fileGlob
= fileGlob
.replaceAll("([^A-Za-z0-9\\-_/])", "\\\\$1");
946 fileGlob
= fileGlob
.replaceAll("\\\\\\*\\\\\\*", ".*");
947 fileGlob
= fileGlob
.replaceAll("\\\\\\*", "[^/]*");
951 * Sets the application root directory, as a prefix for the regexps in
952 * {@link #includeResourcePattern(String)} and friends. This is needed
953 * because we want to match complete filenames relative to root.
957 public void setSourcePrefix(String appRoot
) {
958 this.appRoot
= appRoot
;
959 this.resourceIncludePattern
= null;
960 this.resourceExcludePattern
= null;
961 this.staticIncludePattern
= null;
962 this.staticExcludePattern
= null;
965 public String
getSourcePrefix() {
969 private static String
toNullIfEmptyOrWhitespace(String string
) {
970 if (string
== null || CharMatcher
.WHITESPACE
.matchesAllOf(string
)) {
977 * Represents a {@link java.security.Permission} that needs to be
978 * granted to user code.
980 private static class UserPermission
{
981 private final String className
;
982 private final String name
;
983 private final String actions
;
985 private boolean hasHashCode
= false;
986 private int hashCode
;
988 public UserPermission(String className
, String name
, String actions
) {
989 this.className
= className
;
991 this.actions
= actions
;
994 public String
getClassName() {
998 public String
getName() {
1002 public String
getActions() {
1007 public int hashCode() {
1012 int hash
= className
.hashCode();
1013 hash
= 31 * hash
+ name
.hashCode();
1014 if (actions
!= null) {
1015 hash
= 31 * hash
+ actions
.hashCode();
1024 public boolean equals(Object obj
) {
1025 if (obj
instanceof UserPermission
) {
1026 UserPermission perm
= (UserPermission
) obj
;
1027 if (className
.equals(perm
.className
) && name
.equals(perm
.name
)) {
1028 if (actions
== null ? perm
.actions
== null : actions
.equals(perm
.actions
)) {
1038 * Represents an <include> element within the
1039 * <static-files> element. Currently this includes both a
1040 * pattern and an optional expiration time specification.
1042 public static class StaticFileInclude
{
1043 private final String pattern
;
1044 private final String expiration
;
1045 private final Map
<String
, String
> httpHeaders
;
1047 public StaticFileInclude(String pattern
, String expiration
) {
1048 this.pattern
= pattern
;
1049 this.expiration
= expiration
;
1050 this.httpHeaders
= new LinkedHashMap
<>();
1053 public String
getPattern() {
1057 public Pattern
getRegularExpression() {
1058 return Pattern
.compile(makeFileRegex(pattern
));
1061 public String
getExpiration() {
1065 public Map
<String
, String
> getHttpHeaders() {
1070 public int hashCode() {
1071 return Objects
.hash(pattern
, expiration
, httpHeaders
);
1075 public boolean equals(Object obj
) {
1076 if (!(obj
instanceof StaticFileInclude
)) {
1080 StaticFileInclude other
= (StaticFileInclude
) obj
;
1082 if (pattern
!= null) {
1083 if (!pattern
.equals(other
.pattern
)) {
1087 if (other
.pattern
!= null) {
1092 if (expiration
!= null) {
1093 if (!expiration
.equals(other
.expiration
)) {
1097 if (other
.expiration
!= null) {
1102 if (httpHeaders
!= null) {
1103 if (!httpHeaders
.equals(other
.httpHeaders
)) {
1107 if (other
.httpHeaders
!= null) {
1116 public static class AdminConsolePage
{
1117 private final String name
;
1118 private final String url
;
1120 public AdminConsolePage(String name
, String url
) {
1125 public String
getName() {
1129 public String
getUrl() {
1134 public int hashCode() {
1135 final int prime
= 31;
1137 result
= prime
* result
+ ((name
== null) ?
0 : name
.hashCode());
1138 result
= prime
* result
+ ((url
== null) ?
0 : url
.hashCode());
1143 public boolean equals(Object obj
) {
1144 if (this == obj
) return true;
1145 if (obj
== null) return false;
1146 if (getClass() != obj
.getClass()) return false;
1147 AdminConsolePage other
= (AdminConsolePage
) obj
;
1149 if (other
.name
!= null) return false;
1150 } else if (!name
.equals(other
.name
)) return false;
1152 if (other
.url
!= null) return false;
1153 } else if (!url
.equals(other
.url
)) return false;
1159 * Represents an <error-handler> element. Currently this includes both
1160 * a file name and an optional error code.
1162 public static class ErrorHandler
{
1163 private final String file
;
1164 private final String errorCode
;
1166 public ErrorHandler(String file
, String errorCode
) {
1168 this.errorCode
= errorCode
;
1171 public String
getFile() {
1175 public String
getErrorCode() {
1180 public int hashCode() {
1181 final int prime
= 31;
1183 result
= prime
* result
+ ((file
== null) ?
0 : file
.hashCode());
1184 result
= prime
* result
+
1185 ((errorCode
== null) ?
0 : errorCode
.hashCode());
1190 public boolean equals(Object obj
) {
1191 if (!(obj
instanceof ErrorHandler
)) {
1195 ErrorHandler handler
= (ErrorHandler
) obj
;
1196 if (!file
.equals(handler
.file
)) {
1200 if (errorCode
== null) {
1201 if (handler
.errorCode
!= null) {
1205 if (!errorCode
.equals(handler
.errorCode
)) {
1215 * Represents an <api-config> element. This is a singleton specifying
1216 * url-pattern and servlet-class for the api config server.
1218 public static class ApiConfig
{
1219 private final String servletClass
;
1220 private final String url
;
1222 public ApiConfig(String servletClass
, String url
) {
1223 this.servletClass
= servletClass
;
1227 public String
getservletClass() {
1228 return servletClass
;
1231 public String
getUrl() {
1236 public int hashCode() {
1237 final int prime
= 31;
1239 result
= prime
* result
+ ((servletClass
== null) ?
0 : servletClass
.hashCode());
1240 result
= prime
* result
+ ((url
== null) ?
0 : url
.hashCode());
1245 public boolean equals(Object obj
) {
1246 if (this == obj
) { return true; }
1247 if (obj
== null) { return false; }
1248 if (getClass() != obj
.getClass()) { return false; }
1249 ApiConfig other
= (ApiConfig
) obj
;
1250 if (servletClass
== null) {
1251 if (other
.servletClass
!= null) { return false; }
1252 } else if (!servletClass
.equals(other
.servletClass
)) { return false; }
1254 if (other
.url
!= null) { return false; }
1255 } else if (!url
.equals(other
.url
)) { return false; }
1260 public String
toString() {
1261 return "ApiConfig{servletClass=\"" + servletClass
+ "\", url=\"" + url
+ "\"}";
1266 * Holder for automatic settings.
1268 public static class AutomaticScaling
{
1269 private static final AutomaticScaling EMPTY_SETTINGS
= new AutomaticScaling();
1271 public static final String AUTOMATIC
= "automatic";
1272 private String minPendingLatency
;
1273 private String maxPendingLatency
;
1274 private String minIdleInstances
;
1275 private String maxIdleInstances
;
1276 private String maxConcurrentRequests
;
1278 private Integer minNumInstances
;
1279 private Integer maxNumInstances
;
1280 private Integer coolDownPeriodSec
;
1281 private CpuUtilization cpuUtilization
;
1283 private Integer targetNetworkSentBytesPerSec
;
1284 private Integer targetNetworkSentPacketsPerSec
;
1285 private Integer targetNetworkReceivedBytesPerSec
;
1286 private Integer targetNetworkReceivedPacketsPerSec
;
1287 private Integer targetDiskWriteBytesPerSec
;
1288 private Integer targetDiskWriteOpsPerSec
;
1289 private Integer targetDiskReadBytesPerSec
;
1290 private Integer targetDiskReadOpsPerSec
;
1291 private Integer targetRequestCountPerSec
;
1292 private Integer targetConcurrentRequests
;
1294 public String
getMinPendingLatency() {
1295 return minPendingLatency
;
1299 * Sets minPendingLatency. Normalizes empty and null inputs to null.
1301 public void setMinPendingLatency(String minPendingLatency
) {
1302 this.minPendingLatency
= toNullIfEmptyOrWhitespace(minPendingLatency
);
1305 public String
getMaxPendingLatency() {
1306 return maxPendingLatency
;
1310 * Sets maxPendingLatency. Normalizes empty and null inputs to null.
1312 public void setMaxPendingLatency(String maxPendingLatency
) {
1313 this.maxPendingLatency
= toNullIfEmptyOrWhitespace(maxPendingLatency
);
1316 public String
getMinIdleInstances() {
1317 return minIdleInstances
;
1321 * Sets minIdleInstances. Normalizes empty and null inputs to null.
1323 public void setMinIdleInstances(String minIdleInstances
) {
1324 this.minIdleInstances
= toNullIfEmptyOrWhitespace(minIdleInstances
);
1327 public String
getMaxIdleInstances() {
1328 return maxIdleInstances
;
1332 * Sets maxIdleInstances. Normalizes empty and null inputs to null.
1334 public void setMaxIdleInstances(String maxIdleInstances
) {
1335 this.maxIdleInstances
= toNullIfEmptyOrWhitespace(maxIdleInstances
);
1338 public boolean isEmpty() {
1339 return this.equals(EMPTY_SETTINGS
);
1342 public String
getMaxConcurrentRequests() {
1343 return maxConcurrentRequests
;
1347 * Sets maxConcurrentRequests. Normalizes empty and null inputs to null.
1349 public void setMaxConcurrentRequests(String maxConcurrentRequests
) {
1350 this.maxConcurrentRequests
= toNullIfEmptyOrWhitespace(maxConcurrentRequests
);
1353 public Integer
getMinNumInstances() {
1354 return minNumInstances
;
1357 public void setMinNumInstances(Integer minNumInstances
) {
1358 this.minNumInstances
= minNumInstances
;
1361 public Integer
getMaxNumInstances() {
1362 return maxNumInstances
;
1365 public void setMaxNumInstances(Integer maxNumInstances
) {
1366 this.maxNumInstances
= maxNumInstances
;
1369 public Integer
getCoolDownPeriodSec() {
1370 return coolDownPeriodSec
;
1373 public void setCoolDownPeriodSec(Integer coolDownPeriodSec
) {
1374 this.coolDownPeriodSec
= coolDownPeriodSec
;
1377 public CpuUtilization
getCpuUtilization() {
1378 return cpuUtilization
;
1381 public void setCpuUtilization(CpuUtilization cpuUtilization
) {
1382 this.cpuUtilization
= cpuUtilization
;
1385 public Integer
getTargetNetworkSentBytesPerSec() {
1386 return targetNetworkSentBytesPerSec
;
1389 public void setTargetNetworkSentBytesPerSec(Integer targetNetworkSentBytesPerSec
) {
1390 this.targetNetworkSentBytesPerSec
= targetNetworkSentBytesPerSec
;
1393 public Integer
getTargetNetworkSentPacketsPerSec() {
1394 return targetNetworkSentPacketsPerSec
;
1397 public void setTargetNetworkSentPacketsPerSec(Integer targetNetworkSentPacketsPerSec
) {
1398 this.targetNetworkSentPacketsPerSec
= targetNetworkSentPacketsPerSec
;
1401 public Integer
getTargetNetworkReceivedBytesPerSec() {
1402 return targetNetworkReceivedBytesPerSec
;
1405 public void setTargetNetworkReceivedBytesPerSec(Integer targetNetworkReceivedBytesPerSec
) {
1406 this.targetNetworkReceivedBytesPerSec
= targetNetworkReceivedBytesPerSec
;
1409 public Integer
getTargetNetworkReceivedPacketsPerSec() {
1410 return targetNetworkReceivedPacketsPerSec
;
1413 public void setTargetNetworkReceivedPacketsPerSec(Integer targetNetworkReceivedPacketsPerSec
) {
1414 this.targetNetworkReceivedPacketsPerSec
= targetNetworkReceivedPacketsPerSec
;
1417 public Integer
getTargetDiskWriteBytesPerSec() {
1418 return targetDiskWriteBytesPerSec
;
1421 public void setTargetDiskWriteBytesPerSec(Integer targetDiskWriteBytesPerSec
) {
1422 this.targetDiskWriteBytesPerSec
= targetDiskWriteBytesPerSec
;
1425 public Integer
getTargetDiskWriteOpsPerSec() {
1426 return targetDiskWriteOpsPerSec
;
1429 public void setTargetDiskWriteOpsPerSec(Integer targetDiskWriteOpsPerSec
) {
1430 this.targetDiskWriteOpsPerSec
= targetDiskWriteOpsPerSec
;
1433 public Integer
getTargetDiskReadBytesPerSec() {
1434 return targetDiskReadBytesPerSec
;
1437 public void setTargetDiskReadBytesPerSec(Integer targetDiskReadBytesPerSec
) {
1438 this.targetDiskReadBytesPerSec
= targetDiskReadBytesPerSec
;
1441 public Integer
getTargetDiskReadOpsPerSec() {
1442 return targetDiskReadOpsPerSec
;
1445 public void setTargetDiskReadOpsPerSec(Integer targetDiskReadOpsPerSec
) {
1446 this.targetDiskReadOpsPerSec
= targetDiskReadOpsPerSec
;
1449 public Integer
getTargetRequestCountPerSec() {
1450 return targetRequestCountPerSec
;
1453 public void setTargetRequestCountPerSec(Integer targetRequestCountPerSec
) {
1454 this.targetRequestCountPerSec
= targetRequestCountPerSec
;
1457 public Integer
getTargetConcurrentRequests() {
1458 return targetConcurrentRequests
;
1461 public void setTargetConcurrentRequests(Integer targetConcurrentRequests
) {
1462 this.targetConcurrentRequests
= targetConcurrentRequests
;
1466 public int hashCode() {
1467 return Objects
.hash(maxPendingLatency
, minPendingLatency
, maxIdleInstances
,
1468 minIdleInstances
, maxConcurrentRequests
, minNumInstances
,
1469 maxNumInstances
, coolDownPeriodSec
, cpuUtilization
,
1470 targetNetworkSentBytesPerSec
, targetNetworkSentPacketsPerSec
,
1471 targetNetworkReceivedBytesPerSec
, targetNetworkReceivedPacketsPerSec
,
1472 targetDiskWriteBytesPerSec
, targetDiskWriteOpsPerSec
,
1473 targetDiskReadBytesPerSec
, targetDiskReadOpsPerSec
,
1474 targetRequestCountPerSec
, targetConcurrentRequests
);
1478 public boolean equals(Object obj
) {
1485 if (getClass() != obj
.getClass()) {
1488 AutomaticScaling other
= (AutomaticScaling
) obj
;
1489 return Objects
.equals(maxPendingLatency
, other
.maxPendingLatency
)
1490 && Objects
.equals(minPendingLatency
, other
.minPendingLatency
)
1491 && Objects
.equals(maxIdleInstances
, other
.maxIdleInstances
)
1492 && Objects
.equals(minIdleInstances
, other
.minIdleInstances
)
1493 && Objects
.equals(maxConcurrentRequests
, other
.maxConcurrentRequests
)
1494 && Objects
.equals(minNumInstances
, other
.minNumInstances
)
1495 && Objects
.equals(maxNumInstances
, other
.maxNumInstances
)
1496 && Objects
.equals(coolDownPeriodSec
, other
.coolDownPeriodSec
)
1497 && Objects
.equals(cpuUtilization
, other
.cpuUtilization
)
1498 && Objects
.equals(targetNetworkSentBytesPerSec
, other
.targetNetworkSentBytesPerSec
)
1499 && Objects
.equals(targetNetworkSentPacketsPerSec
, other
.targetNetworkSentPacketsPerSec
)
1500 && Objects
.equals(targetNetworkReceivedBytesPerSec
,
1501 other
.targetNetworkReceivedBytesPerSec
)
1502 && Objects
.equals(targetNetworkReceivedPacketsPerSec
,
1503 other
.targetNetworkReceivedPacketsPerSec
)
1504 && Objects
.equals(targetDiskWriteBytesPerSec
, other
.targetDiskWriteBytesPerSec
)
1505 && Objects
.equals(targetDiskWriteOpsPerSec
, other
.targetDiskWriteOpsPerSec
)
1506 && Objects
.equals(targetDiskReadBytesPerSec
, other
.targetDiskReadBytesPerSec
)
1507 && Objects
.equals(targetDiskReadOpsPerSec
, other
.targetDiskReadOpsPerSec
)
1508 && Objects
.equals(targetRequestCountPerSec
, other
.targetRequestCountPerSec
)
1509 && Objects
.equals(targetConcurrentRequests
, other
.targetConcurrentRequests
);
1513 public String
toString() {
1514 return "AutomaticScaling [minPendingLatency=" + minPendingLatency
1515 + ", maxPendingLatency=" + maxPendingLatency
1516 + ", minIdleInstances=" + minIdleInstances
1517 + ", maxIdleInstances=" + maxIdleInstances
1518 + ", maxConcurrentRequests=" + maxConcurrentRequests
1519 + ", minNumInstances=" + minNumInstances
1520 + ", maxNumInstances=" + maxNumInstances
1521 + ", coolDownPeriodSec=" + coolDownPeriodSec
1522 + ", cpuUtilization=" + cpuUtilization
1523 + ", targetNetworkSentBytesPerSec=" + targetNetworkSentBytesPerSec
1524 + ", targetNetworkSentPacketsPerSec=" + targetNetworkSentPacketsPerSec
1525 + ", targetNetworkReceivedBytesPerSec=" + targetNetworkReceivedBytesPerSec
1526 + ", targetNetworkReceivedPacketsPerSec=" + targetNetworkReceivedPacketsPerSec
1527 + ", targetDiskWriteBytesPerSec=" + targetDiskWriteBytesPerSec
1528 + ", targetDiskWriteOpsPerSec=" + targetDiskWriteOpsPerSec
1529 + ", targetDiskReadBytesPerSec=" + targetDiskReadBytesPerSec
1530 + ", targetDiskReadOpsPerSec=" + targetDiskReadOpsPerSec
1531 + ", targetRequestCountPerSec=" + targetRequestCountPerSec
1532 + ", targetConcurrentRequests=" + targetConcurrentRequests
1538 * Holder for CPU utilization.
1540 public static class CpuUtilization
{
1541 private static final CpuUtilization EMPTY_SETTINGS
= new CpuUtilization();
1542 private Double targetUtilization
;
1543 private Integer aggregationWindowLengthSec
;
1545 public Double
getTargetUtilization() {
1546 return targetUtilization
;
1549 public void setTargetUtilization(Double targetUtilization
) {
1550 this.targetUtilization
= targetUtilization
;
1553 public Integer
getAggregationWindowLengthSec() {
1554 return aggregationWindowLengthSec
;
1557 public void setAggregationWindowLengthSec(Integer aggregationWindowLengthSec
) {
1558 this.aggregationWindowLengthSec
= aggregationWindowLengthSec
;
1561 public boolean isEmpty() {
1562 return this.equals(EMPTY_SETTINGS
);
1566 public int hashCode() {
1567 return Objects
.hash(targetUtilization
, aggregationWindowLengthSec
);
1571 public boolean equals(Object obj
) {
1578 if (getClass() != obj
.getClass()) {
1581 CpuUtilization other
= (CpuUtilization
) obj
;
1582 return Objects
.equals(targetUtilization
, other
.targetUtilization
)
1583 && Objects
.equals(aggregationWindowLengthSec
, other
.aggregationWindowLengthSec
);
1587 public String
toString() {
1588 return "CpuUtilization [targetUtilization=" + targetUtilization
1589 + ", aggregationWindowLengthSec=" + aggregationWindowLengthSec
+ "]";
1594 * Holder for health check.
1596 public static class HealthCheck
{
1597 private static final HealthCheck EMPTY_SETTINGS
= new HealthCheck();
1599 private boolean enableHealthCheck
= true;
1600 private Integer checkIntervalSec
;
1601 private Integer timeoutSec
;
1602 private Integer unhealthyThreshold
;
1603 private Integer healthyThreshold
;
1604 private Integer restartThreshold
;
1605 private String host
;
1607 public boolean getEnableHealthCheck() {
1608 return enableHealthCheck
;
1611 * Sets enableHealthCheck.
1613 public void setEnableHealthCheck(boolean enableHealthCheck
) {
1614 this.enableHealthCheck
= enableHealthCheck
;
1617 public Integer
getCheckIntervalSec() {
1618 return checkIntervalSec
;
1621 * Sets checkIntervalSec.
1623 public void setCheckIntervalSec(Integer checkIntervalSec
) {
1624 this.checkIntervalSec
= checkIntervalSec
;
1627 public Integer
getTimeoutSec() {
1633 public void setTimeoutSec(Integer timeoutSec
) {
1634 this.timeoutSec
= timeoutSec
;
1637 public Integer
getUnhealthyThreshold() {
1638 return unhealthyThreshold
;
1642 * Sets unhealthyThreshold.
1644 public void setUnhealthyThreshold(Integer unhealthyThreshold
) {
1645 this.unhealthyThreshold
= unhealthyThreshold
;
1648 public Integer
getHealthyThreshold() {
1649 return healthyThreshold
;
1653 * Sets healthyThreshold.
1656 public void setHealthyThreshold(Integer healthyThreshold
) {
1657 this.healthyThreshold
= healthyThreshold
;
1660 public Integer
getRestartThreshold() {
1661 return restartThreshold
;
1665 * Sets restartThreshold.
1667 public void setRestartThreshold(Integer restartThreshold
) {
1668 this.restartThreshold
= restartThreshold
;
1671 public String
getHost() {
1676 * Sets host. Normalizes empty and null inputs to null.
1678 public void setHost(String host
) {
1679 this.host
= toNullIfEmptyOrWhitespace(host
);
1682 public boolean isEmpty() {
1683 return this.equals(EMPTY_SETTINGS
);
1687 public int hashCode() {
1688 return Objects
.hash(enableHealthCheck
, checkIntervalSec
, timeoutSec
, unhealthyThreshold
,
1689 healthyThreshold
, restartThreshold
, host
);
1693 public boolean equals(Object obj
) {
1700 if (getClass() != obj
.getClass()) {
1703 HealthCheck other
= (HealthCheck
) obj
;
1704 return Objects
.equals(enableHealthCheck
, other
.enableHealthCheck
)
1705 && Objects
.equals(checkIntervalSec
, other
.checkIntervalSec
)
1706 && Objects
.equals(timeoutSec
, other
.timeoutSec
)
1707 && Objects
.equals(unhealthyThreshold
, other
.unhealthyThreshold
)
1708 && Objects
.equals(healthyThreshold
, other
.healthyThreshold
)
1709 && Objects
.equals(restartThreshold
, other
.restartThreshold
)
1710 && Objects
.equals(host
, other
.host
);
1714 public String
toString() {
1715 return "HealthCheck [enableHealthCheck=" + enableHealthCheck
1716 + ", checkIntervalSec=" + checkIntervalSec
1717 + ", timeoutSec=" + timeoutSec
1718 + ", unhealthyThreshold=" + unhealthyThreshold
1719 + ", healthyThreshold=" + healthyThreshold
1720 + ", restartThreshold=" + restartThreshold
1721 + ", host=" + host
+ "]";
1726 * Holder for Resources
1728 public static class Resources
{
1729 private static final Resources EMPTY_SETTINGS
= new Resources();
1733 public double getCpu() {
1737 public void setCpu(double cpu
) {
1741 private double memory_gb
;
1743 public double getMemoryGb() {
1747 public void setMemoryGb(double memory_gb
) {
1748 this.memory_gb
= memory_gb
;
1751 private int disk_size_gb
;
1753 public int getDiskSizeGb() {
1754 return disk_size_gb
;
1757 public void setDiskSizeGb(int disk_size_gb
) {
1758 this.disk_size_gb
= disk_size_gb
;
1761 public boolean isEmpty() {
1762 return this.equals(EMPTY_SETTINGS
);
1766 public int hashCode() {
1767 return Objects
.hash(cpu
, memory_gb
, disk_size_gb
);
1771 public boolean equals(Object obj
) {
1778 if (getClass() != obj
.getClass()) {
1781 Resources other
= (Resources
) obj
;
1782 return Objects
.equals(cpu
, other
.cpu
) &&
1783 Objects
.equals(memory_gb
, other
.memory_gb
) &&
1784 Objects
.equals(disk_size_gb
, other
.disk_size_gb
);
1788 public String
toString() {
1789 return "Resources [" + "cpu=" + cpu
+
1790 ", memory_gb=" + memory_gb
+
1791 ", disk_size_gb=" + disk_size_gb
+ "]";
1796 * Holder for network.
1798 public static class Network
{
1799 private static final Network EMPTY_SETTINGS
= new Network();
1801 private String instanceTag
;
1803 public String
getInstanceTag() {
1807 public void setInstanceTag(String instanceTag
) {
1808 this.instanceTag
= instanceTag
;
1811 private final List
<String
> forwardedPorts
= Lists
.newArrayList();
1813 public List
<String
> getForwardedPorts() {
1814 return Collections
.unmodifiableList(forwardedPorts
);
1817 public void addForwardedPort(String forwardedPort
) {
1818 forwardedPorts
.add(forwardedPort
);
1821 private String name
;
1823 public String
getName() {
1827 public void setName(String name
) {
1831 public boolean isEmpty() {
1832 return this.equals(EMPTY_SETTINGS
);
1836 public int hashCode() {
1837 return Objects
.hash(forwardedPorts
, instanceTag
);
1841 public boolean equals(Object obj
) {
1848 if (getClass() != obj
.getClass()) {
1851 Network other
= (Network
) obj
;
1852 return Objects
.equals(forwardedPorts
, other
.forwardedPorts
)
1853 && Objects
.equals(instanceTag
, other
.instanceTag
);
1857 public String
toString() {
1858 return "Network [forwardedPorts=" + forwardedPorts
+ ", instanceTag=" + instanceTag
+ "]";
1863 * Holder for manual settings.
1865 public static class ManualScaling
{
1866 private static final ManualScaling EMPTY_SETTINGS
= new ManualScaling();
1868 private String instances
;
1870 public String
getInstances() {
1875 * Sets instances. Normalizes empty and null inputs to null.
1877 public void setInstances(String instances
) {
1878 this.instances
= toNullIfEmptyOrWhitespace(instances
);
1881 public boolean isEmpty() {
1882 return this.equals(EMPTY_SETTINGS
);
1886 public int hashCode() {
1887 return Objects
.hash(instances
);
1891 public boolean equals(Object obj
) {
1898 if (getClass() != obj
.getClass()) {
1901 ManualScaling other
= (ManualScaling
) obj
;
1902 return Objects
.equals(instances
, other
.instances
);
1906 public String
toString() {
1907 return "ManualScaling [" + "instances=" + instances
+ "]";
1912 * Holder for basic settings.
1914 public static class BasicScaling
{
1915 private static final BasicScaling EMPTY_SETTINGS
= new BasicScaling();
1917 private String maxInstances
;
1918 private String idleTimeout
;
1920 public String
getMaxInstances() {
1921 return maxInstances
;
1924 public String
getIdleTimeout() {
1929 * Sets maxInstances. Normalizes empty and null inputs to null.
1931 public void setMaxInstances(String maxInstances
) {
1932 this.maxInstances
= toNullIfEmptyOrWhitespace(maxInstances
);
1936 * Sets idleTimeout. Normalizes empty and null inputs to null.
1938 public void setIdleTimeout(String idleTimeout
) {
1939 this.idleTimeout
= toNullIfEmptyOrWhitespace(idleTimeout
);
1942 public boolean isEmpty() {
1943 return this.equals(EMPTY_SETTINGS
);
1947 public int hashCode() {
1948 return Objects
.hash(maxInstances
, idleTimeout
);
1952 public boolean equals(Object obj
) {
1959 if (getClass() != obj
.getClass()) {
1962 BasicScaling other
= (BasicScaling
) obj
;
1963 return Objects
.equals(maxInstances
, other
.maxInstances
)
1964 && Objects
.equals(idleTimeout
, other
.idleTimeout
);
1968 public String
toString() {
1969 return "BasicScaling [" + "maxInstances=" + maxInstances
1970 + ", idleTimeout=" + idleTimeout
+ "]";
1975 * Represents a <pagespeed> element. This is used to specify configuration for the Page
1976 * Speed Service, which can be used to automatically optimize the loading speed of app engine
1979 public static class Pagespeed
{
1980 private final List
<String
> urlBlacklist
= Lists
.newArrayList();
1981 private final List
<String
> domainsToRewrite
= Lists
.newArrayList();
1982 private final List
<String
> enabledRewriters
= Lists
.newArrayList();
1983 private final List
<String
> disabledRewriters
= Lists
.newArrayList();
1985 public void addUrlBlacklist(String url
) {
1986 urlBlacklist
.add(url
);
1989 public List
<String
> getUrlBlacklist() {
1990 return Collections
.unmodifiableList(urlBlacklist
);
1993 public void addDomainToRewrite(String domain
) {
1994 domainsToRewrite
.add(domain
);
1997 public List
<String
> getDomainsToRewrite() {
1998 return Collections
.unmodifiableList(domainsToRewrite
);
2001 public void addEnabledRewriter(String rewriter
) {
2002 enabledRewriters
.add(rewriter
);
2005 public List
<String
> getEnabledRewriters() {
2006 return Collections
.unmodifiableList(enabledRewriters
);
2009 public void addDisabledRewriter(String rewriter
) {
2010 disabledRewriters
.add(rewriter
);
2013 public List
<String
> getDisabledRewriters() {
2014 return Collections
.unmodifiableList(disabledRewriters
);
2017 public boolean isEmpty() {
2018 return urlBlacklist
.isEmpty() && domainsToRewrite
.isEmpty() && enabledRewriters
.isEmpty()
2019 && disabledRewriters
.isEmpty();
2023 public int hashCode() {
2024 return Objects
.hash(urlBlacklist
, domainsToRewrite
, enabledRewriters
, disabledRewriters
);
2028 public boolean equals(Object obj
) {
2035 if (getClass() != obj
.getClass()) {
2038 Pagespeed other
= (Pagespeed
) obj
;
2039 return Objects
.equals(urlBlacklist
, other
.urlBlacklist
)
2040 && Objects
.equals(domainsToRewrite
, other
.domainsToRewrite
)
2041 && Objects
.equals(enabledRewriters
, other
.enabledRewriters
)
2042 && Objects
.equals(disabledRewriters
, other
.disabledRewriters
);
2046 public String
toString() {
2047 return "Pagespeed [urlBlacklist=" + urlBlacklist
+ ", domainsToRewrite=" + domainsToRewrite
2048 + ", enabledRewriters=" + enabledRewriters
+ ", disabledRewriters=" + disabledRewriters
2053 public static class ClassLoaderConfig
{
2054 private final List
<PrioritySpecifierEntry
> entries
= Lists
.newArrayList();
2056 public void add(PrioritySpecifierEntry entry
) {
2060 public List
<PrioritySpecifierEntry
> getEntries() {
2065 public int hashCode() {
2066 final int prime
= 31;
2068 result
= prime
* result
+ ((entries
== null) ?
0 : entries
.hashCode());
2073 public boolean equals(Object obj
) {
2074 if (this == obj
) return true;
2075 if (obj
== null) return false;
2076 if (getClass() != obj
.getClass()) return false;
2077 ClassLoaderConfig other
= (ClassLoaderConfig
) obj
;
2078 if (entries
== null) {
2079 if (other
.entries
!= null) return false;
2080 } else if (!entries
.equals(other
.entries
)) return false;
2085 public String
toString() {
2086 return "ClassLoaderConfig{entries=\"" + entries
+ "\"}";
2090 public static class PrioritySpecifierEntry
{
2091 private String filename
;
2092 private Double priority
;
2094 private void checkNotAlreadySet() {
2095 if (filename
!= null) {
2096 throw new AppEngineConfigException("Found more that one file name matching tag. "
2097 + "Only one of 'filename' attribute allowed.");
2101 public String
getFilename() {
2105 public void setFilename(String filename
) {
2106 checkNotAlreadySet();
2107 this.filename
= filename
;
2110 public Double
getPriority() {
2114 public double getPriorityValue() {
2115 if (priority
== null) {
2121 public void setPriority(String priority
) {
2122 if (this.priority
!= null) {
2123 throw new AppEngineConfigException("The 'priority' tag may only be specified once.");
2126 if (priority
== null) {
2127 this.priority
= null;
2131 this.priority
= Double
.parseDouble(priority
);
2134 public void checkClassLoaderConfig() {
2135 if (filename
== null) {
2136 throw new AppEngineConfigException("Must have a filename attribute.");
2141 public int hashCode() {
2142 final int prime
= 31;
2144 result
= prime
* result
+ ((filename
== null) ?
0 : filename
.hashCode());
2145 result
= prime
* result
+ ((priority
== null) ?
0 : priority
.hashCode());
2150 public boolean equals(Object obj
) {
2151 if (this == obj
) return true;
2152 if (obj
== null) return false;
2153 if (getClass() != obj
.getClass()) return false;
2154 PrioritySpecifierEntry other
= (PrioritySpecifierEntry
) obj
;
2155 if (filename
== null) {
2156 if (other
.filename
!= null) return false;
2157 } else if (!filename
.equals(other
.filename
)) return false;
2158 if (priority
== null) {
2159 if (other
.priority
!= null) return false;
2160 } else if (!priority
.equals(other
.priority
)) return false;
2165 public String
toString() {
2166 return "PrioritySpecifierEntry{filename=\"" + filename
+ "\", priority=\"" + priority
+ "\"}";