1 // Copyright 2008 Google Inc. All Rights Reserved.
2 package com
.google
.apphosting
.utils
.config
;
4 import com
.google
.common
.base
.StringUtil
;
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 instanceClass
;
59 private final AutomaticScaling automaticScaling
;
60 private final ManualScaling manualScaling
;
61 private final BasicScaling basicScaling
;
63 private String sourceLanguage
;
64 private boolean sslEnabled
= true;
65 private boolean useSessions
= false;
66 private boolean asyncSessionPersistence
= false;
67 private String asyncSessionPersistenceQueueName
;
69 private final List
<StaticFileInclude
> staticFileIncludes
;
70 private final List
<String
> staticFileExcludes
;
71 private final List
<String
> resourceFileIncludes
;
72 private final List
<String
> resourceFileExcludes
;
74 private Pattern staticIncludePattern
;
75 private Pattern staticExcludePattern
;
76 private Pattern resourceIncludePattern
;
77 private Pattern resourceExcludePattern
;
79 private String publicRoot
= "";
81 private String appRoot
;
83 private final Set
<String
> inboundServices
;
84 private boolean precompilationEnabled
= true;
86 private final List
<AdminConsolePage
> adminConsolePages
= new ArrayList
<AdminConsolePage
>();
87 private final List
<ErrorHandler
> errorHandlers
= new ArrayList
<ErrorHandler
>();
89 private ClassLoaderConfig classLoaderConfig
;
91 private String urlStreamHandlerType
= null;
93 private boolean threadsafe
= false;
94 private boolean threadsafeValueProvided
= false;
96 private String autoIdPolicy
;
98 private boolean codeLock
= false;
99 private boolean useVm
= false;
100 private ApiConfig apiConfig
;
101 private final List
<String
> apiEndpointIds
;
102 private Pagespeed pagespeed
;
105 * Represent user's choice w.r.t the usage of Google's customized connector-j.
107 public static enum UseGoogleConnectorJ
{
112 private UseGoogleConnectorJ useGoogleConnectorJ
= UseGoogleConnectorJ
.NOT_STATED_BY_USER
;
114 public AppEngineWebXml() {
115 automaticScaling
= new AutomaticScaling();
116 manualScaling
= new ManualScaling();
117 basicScaling
= new BasicScaling();
118 healthCheck
= new HealthCheck();
119 resources
= new Resources();
120 network
= new Network();
122 staticFileIncludes
= new ArrayList
<StaticFileInclude
>();
123 staticFileExcludes
= new ArrayList
<String
>();
124 staticFileExcludes
.add("WEB-INF/**");
125 staticFileExcludes
.add("**.jsp");
126 resourceFileIncludes
= new ArrayList
<String
>();
127 resourceFileExcludes
= new ArrayList
<String
>();
128 inboundServices
= new LinkedHashSet
<String
>();
129 apiEndpointIds
= new ArrayList
<String
>();
132 public AppEngineWebXml
clone() {
134 return (AppEngineWebXml
) super.clone();
135 } catch (CloneNotSupportedException ce
) {
136 throw new RuntimeException("Could not clone AppEngineWebXml", ce
);
141 * @return An unmodifiable map whose entries correspond to the
142 * system properties defined in appengine-web.xml.
144 public Map
<String
, String
> getSystemProperties() {
145 return Collections
.unmodifiableMap(systemProperties
);
148 public void addSystemProperty(String key
, String value
) {
149 systemProperties
.put(key
, value
);
153 * @return An unmodifiable map whose entires correspond to the
154 * vm settings defined in appengine-web.xml.
156 public Map
<String
, String
> getBetaSettings() {
157 return Collections
.unmodifiableMap(betaSettings
);
160 public void addBetaSetting(String key
, String value
) {
161 betaSettings
.put(key
, value
);
164 public HealthCheck
getHealthCheck() {
168 public Resources
getResources() {
172 public Network
getNetwork() {
177 * @return An unmodifiable map whose entires correspond to the
178 * environment variables defined in appengine-web.xml.
180 public Map
<String
, String
> getEnvironmentVariables() {
181 return Collections
.unmodifiableMap(envVariables
);
184 public void addEnvironmentVariable(String key
, String value
) {
185 envVariables
.put(key
, value
);
188 public String
getAppId() {
192 public void setAppId(String appId
) {
196 public String
getMajorVersionId() {
197 return majorVersionId
;
200 public void setMajorVersionId(String majorVersionId
) {
201 this.majorVersionId
= majorVersionId
;
204 public String
getSourceLanguage() {
205 return this.sourceLanguage
;
208 public void setSourceLanguage(String sourceLanguage
) {
209 this.sourceLanguage
= sourceLanguage
;
212 public String
getModule() {
217 * Sets instanceClass (aka class in the xml/yaml files). Normalizes empty and null
220 public void setInstanceClass(String instanceClass
) {
221 this.instanceClass
= StringUtil
.toNullIfEmptyOrWhitespace(instanceClass
);
224 public String
getInstanceClass() {
225 return instanceClass
;
228 public AutomaticScaling
getAutomaticScaling() {
229 return automaticScaling
;
232 public ManualScaling
getManualScaling() {
233 return manualScaling
;
236 public BasicScaling
getBasicScaling() {
240 public ScalingType
getScalingType() {
241 if (!getBasicScaling().isEmpty()) {
242 return ScalingType
.BASIC
;
243 } else if (!getManualScaling().isEmpty()) {
244 return ScalingType
.MANUAL
;
246 return ScalingType
.AUTOMATIC
;
250 public void setModule(String module
) {
251 this.module
= module
;
254 public void setSslEnabled(boolean ssl
) {
258 public boolean getSslEnabled() {
262 public void setSessionsEnabled(boolean sessions
) {
263 useSessions
= sessions
;
266 public boolean getSessionsEnabled() {
270 public void setAsyncSessionPersistence(boolean asyncSessionPersistence
) {
271 this.asyncSessionPersistence
= asyncSessionPersistence
;
274 public boolean getAsyncSessionPersistence() {
275 return asyncSessionPersistence
;
278 public void setAsyncSessionPersistenceQueueName(String asyncSessionPersistenceQueueName
) {
279 this.asyncSessionPersistenceQueueName
= asyncSessionPersistenceQueueName
;
282 public String
getAsyncSessionPersistenceQueueName() {
283 return asyncSessionPersistenceQueueName
;
286 public List
<StaticFileInclude
> getStaticFileIncludes() {
287 return staticFileIncludes
;
290 public List
<String
> getStaticFileExcludes() {
291 return staticFileExcludes
;
294 public StaticFileInclude
includeStaticPattern(String pattern
, String expiration
) {
295 staticIncludePattern
= null;
296 StaticFileInclude staticFileInclude
= new StaticFileInclude(pattern
, expiration
);
297 staticFileIncludes
.add(staticFileInclude
);
298 return staticFileInclude
;
301 public void excludeStaticPattern(String url
) {
302 staticExcludePattern
= null;
303 staticFileExcludes
.add(url
);
306 public List
<String
> getResourcePatterns() {
307 return resourceFileIncludes
;
310 public List
<String
> getResourceFileExcludes() {
311 return resourceFileExcludes
;
314 public void includeResourcePattern(String url
) {
315 resourceExcludePattern
= null;
316 resourceFileIncludes
.add(url
);
319 public void excludeResourcePattern(String url
) {
320 resourceIncludePattern
= null;
321 resourceFileExcludes
.add(url
);
324 public void addUserPermission(String className
, String name
, String actions
) {
325 if (className
.startsWith("java.")) {
326 throw new AppEngineConfigException("Cannot specify user-permissions for " +
327 "classes in java.* packages.");
330 userPermissions
.add(new UserPermission(className
, name
, actions
));
333 public Permissions
getUserPermissions() {
334 Permissions permissions
= new Permissions();
335 for (UserPermission permission
: userPermissions
) {
336 permissions
.add(new UnresolvedPermission(permission
.getClassName(),
337 permission
.getName(),
338 permission
.getActions(),
341 permissions
.setReadOnly();
345 public void setPublicRoot(String root
) {
346 if (root
.indexOf('*') != -1) {
347 throw new AppEngineConfigException("public-root cannot contain wildcards");
349 if (root
.endsWith("/")) {
350 root
= root
.substring(0, root
.length() - 1);
352 if (root
.length() > 0 && !root
.startsWith("/")) {
355 staticIncludePattern
= null;
359 public String
getPublicRoot() {
363 public void addInboundService(String service
) {
364 inboundServices
.add(service
);
367 public Set
<String
> getInboundServices() {
368 return inboundServices
;
371 public boolean getPrecompilationEnabled() {
372 return precompilationEnabled
;
375 public void setPrecompilationEnabled(boolean precompilationEnabled
) {
376 this.precompilationEnabled
= precompilationEnabled
;
379 public boolean getWarmupRequestsEnabled() {
380 return inboundServices
.contains(WARMUP_SERVICE
);
383 public void setWarmupRequestsEnabled(boolean warmupRequestsEnabled
) {
384 if (warmupRequestsEnabled
) {
385 inboundServices
.add(WARMUP_SERVICE
);
387 inboundServices
.remove(WARMUP_SERVICE
);
391 public List
<AdminConsolePage
> getAdminConsolePages() {
392 return Collections
.unmodifiableList(adminConsolePages
);
395 public void addAdminConsolePage(AdminConsolePage page
) {
396 adminConsolePages
.add(page
);
399 public List
<ErrorHandler
> getErrorHandlers() {
400 return Collections
.unmodifiableList(errorHandlers
);
403 public void addErrorHandler(ErrorHandler handler
) {
404 errorHandlers
.add(handler
);
407 public boolean getThreadsafe() {
411 public boolean getThreadsafeValueProvided() {
412 return threadsafeValueProvided
;
415 public void setThreadsafe(boolean threadsafe
) {
416 this.threadsafe
= threadsafe
;
417 this.threadsafeValueProvided
= true;
420 public void setAutoIdPolicy(String policy
) {
421 autoIdPolicy
= policy
;
424 public String
getAutoIdPolicy() {
428 public boolean getCodeLock() {
432 public void setCodeLock(boolean codeLock
) {
433 this.codeLock
= codeLock
;
436 public void setUseVm(boolean useVm
) {
440 public boolean getUseVm() {
444 public ApiConfig
getApiConfig() {
448 public void setApiConfig(ApiConfig config
) {
452 public ClassLoaderConfig
getClassLoaderConfig() {
453 return classLoaderConfig
;
456 public void setClassLoaderConfig(ClassLoaderConfig classLoaderConfig
) {
457 if (this.classLoaderConfig
!= null) {
458 throw new AppEngineConfigException("class-loader-config may only be specified once.");
460 this.classLoaderConfig
= classLoaderConfig
;
463 public String
getUrlStreamHandlerType() {
464 return urlStreamHandlerType
;
467 public void setUrlStreamHandlerType(String urlStreamHandlerType
) {
468 if (this.classLoaderConfig
!= null) {
469 throw new AppEngineConfigException("url-stream-handler may only be specified once.");
471 if (!URL_HANDLER_URLFETCH
.equals(urlStreamHandlerType
)
472 && !URL_HANDLER_NATIVE
.equals(urlStreamHandlerType
)) {
473 throw new AppEngineConfigException(
474 "url-stream-handler must be " + URL_HANDLER_URLFETCH
+ " or " + URL_HANDLER_NATIVE
+
475 " given " + urlStreamHandlerType
);
477 this.urlStreamHandlerType
= urlStreamHandlerType
;
481 * Returns true if {@code url} matches one of the servlets or servlet
482 * filters listed in this web.xml that has api-endpoint set to true.
484 public boolean isApiEndpoint(String id
) {
485 return apiEndpointIds
.contains(id
);
488 public void addApiEndpoint(String id
) {
489 apiEndpointIds
.add(id
);
492 public Pagespeed
getPagespeed() {
496 public void setPagespeed(Pagespeed pagespeed
) {
497 this.pagespeed
= pagespeed
;
500 public void setUseGoogleConnectorJ(boolean useGoogleConnectorJ
) {
501 if (useGoogleConnectorJ
) {
502 this.useGoogleConnectorJ
= UseGoogleConnectorJ
.TRUE
;
504 this.useGoogleConnectorJ
= UseGoogleConnectorJ
.FALSE
;
508 public UseGoogleConnectorJ
getUseGoogleConnectorJ() {
509 return useGoogleConnectorJ
;
513 public String
toString() {
514 return "AppEngineWebXml{" +
515 "systemProperties=" + systemProperties
+
516 ", envVariables=" + envVariables
+
517 ", userPermissions=" + userPermissions
+
518 ", appId='" + appId
+ '\'' +
519 ", majorVersionId='" + majorVersionId
+ '\'' +
520 ", sourceLanguage='" + sourceLanguage
+ '\'' +
521 ", module='" + module
+ '\'' +
522 ", instanceClass='" + instanceClass
+ '\'' +
523 ", automaticScaling=" + automaticScaling
+
524 ", manualScaling=" + manualScaling
+
525 ", basicScaling=" + basicScaling
+
526 ", healthCheck=" + healthCheck
+
527 ", resources=" + resources
+
528 ", network=" + network
+
529 ", sslEnabled=" + sslEnabled
+
530 ", useSessions=" + useSessions
+
531 ", asyncSessionPersistence=" + asyncSessionPersistence
+
532 ", asyncSessionPersistenceQueueName='" + asyncSessionPersistenceQueueName
+ '\'' +
533 ", staticFileIncludes=" + staticFileIncludes
+
534 ", staticFileExcludes=" + staticFileExcludes
+
535 ", resourceFileIncludes=" + resourceFileIncludes
+
536 ", resourceFileExcludes=" + resourceFileExcludes
+
537 ", staticIncludePattern=" + staticIncludePattern
+
538 ", staticExcludePattern=" + staticExcludePattern
+
539 ", resourceIncludePattern=" + resourceIncludePattern
+
540 ", resourceExcludePattern=" + resourceExcludePattern
+
541 ", publicRoot='" + publicRoot
+ '\'' +
542 ", appRoot='" + appRoot
+ '\'' +
543 ", inboundServices=" + inboundServices
+
544 ", precompilationEnabled=" + precompilationEnabled
+
545 ", adminConsolePages=" + adminConsolePages
+
546 ", errorHandlers=" + errorHandlers
+
547 ", threadsafe=" + threadsafe
+
548 ", threadsafeValueProvided=" + threadsafeValueProvided
+
549 ", autoIdPolicy=" + autoIdPolicy
+
550 ", codeLock=" + codeLock
+
551 ", apiConfig=" + apiConfig
+
552 ", apiEndpointIds=" + apiEndpointIds
+
553 ", pagespeed=" + pagespeed
+
554 ", classLoaderConfig=" + classLoaderConfig
+
555 ", urlStreamHandlerType=" +
556 (urlStreamHandlerType
== null ? URL_HANDLER_URLFETCH
: urlStreamHandlerType
) +
557 ", useGoogleConnectorJ=" + useGoogleConnectorJ
+
562 public boolean equals(Object o
) {
566 if (o
== null || getClass() != o
.getClass()) {
570 AppEngineWebXml that
= (AppEngineWebXml
) o
;
572 if (asyncSessionPersistence
!= that
.asyncSessionPersistence
) {
575 if (precompilationEnabled
!= that
.precompilationEnabled
) {
578 if (sslEnabled
!= that
.sslEnabled
) {
581 if (threadsafe
!= that
.threadsafe
) {
584 if (threadsafeValueProvided
!= that
.threadsafeValueProvided
) {
587 if (autoIdPolicy
!= null ?
!autoIdPolicy
.equals(that
.autoIdPolicy
)
588 : that
.autoIdPolicy
!= null) {
591 if (codeLock
!= that
.codeLock
) {
594 if (useSessions
!= that
.useSessions
) {
597 if (adminConsolePages
!= null ?
!adminConsolePages
.equals(that
.adminConsolePages
)
598 : that
.adminConsolePages
!= null) {
601 if (appId
!= null ?
!appId
.equals(that
.appId
) : that
.appId
!= null) {
604 if (majorVersionId
!= null ?
!majorVersionId
.equals(that
.majorVersionId
)
605 : that
.majorVersionId
!= null) {
608 if (module
!= null ?
!module
.equals(that
.module
) : that
.module
!= null) {
611 if (instanceClass
!= null ?
!instanceClass
.equals(that
.instanceClass
)
612 : that
.instanceClass
!= null) {
615 if (!automaticScaling
.equals(that
.automaticScaling
)) {
618 if (!manualScaling
.equals(that
.manualScaling
)) {
621 if (!basicScaling
.equals(that
.basicScaling
)) {
624 if (appRoot
!= null ?
!appRoot
.equals(that
.appRoot
) : that
.appRoot
!= null) {
627 if (asyncSessionPersistenceQueueName
!= null ?
!asyncSessionPersistenceQueueName
628 .equals(that
.asyncSessionPersistenceQueueName
)
629 : that
.asyncSessionPersistenceQueueName
!= null) {
632 if (envVariables
!= null ?
!envVariables
.equals(that
.envVariables
)
633 : that
.envVariables
!= null) {
636 if (errorHandlers
!= null ?
!errorHandlers
.equals(that
.errorHandlers
)
637 : that
.errorHandlers
!= null) {
640 if (inboundServices
!= null ?
!inboundServices
.equals(that
.inboundServices
)
641 : that
.inboundServices
!= null) {
644 if (majorVersionId
!= null ?
!majorVersionId
.equals(that
.majorVersionId
)
645 : that
.majorVersionId
!= null) {
648 if (sourceLanguage
!= null ?
!sourceLanguage
.equals(that
.sourceLanguage
)
649 : that
.sourceLanguage
!= null) {
652 if (publicRoot
!= null ?
!publicRoot
.equals(that
.publicRoot
) : that
.publicRoot
!= null) {
655 if (resourceExcludePattern
!= null ?
!resourceExcludePattern
.equals(that
.resourceExcludePattern
)
656 : that
.resourceExcludePattern
!= null) {
659 if (resourceFileExcludes
!= null ?
!resourceFileExcludes
.equals(that
.resourceFileExcludes
)
660 : that
.resourceFileExcludes
!= null) {
663 if (resourceFileIncludes
!= null ?
!resourceFileIncludes
.equals(that
.resourceFileIncludes
)
664 : that
.resourceFileIncludes
!= null) {
667 if (resourceIncludePattern
!= null ?
!resourceIncludePattern
.equals(that
.resourceIncludePattern
)
668 : that
.resourceIncludePattern
!= null) {
671 if (staticExcludePattern
!= null ?
!staticExcludePattern
.equals(that
.staticExcludePattern
)
672 : that
.staticExcludePattern
!= null) {
675 if (staticFileExcludes
!= null ?
!staticFileExcludes
.equals(that
.staticFileExcludes
)
676 : that
.staticFileExcludes
!= null) {
679 if (staticFileIncludes
!= null ?
!staticFileIncludes
.equals(that
.staticFileIncludes
)
680 : that
.staticFileIncludes
!= null) {
683 if (staticIncludePattern
!= null ?
!staticIncludePattern
.equals(that
.staticIncludePattern
)
684 : that
.staticIncludePattern
!= null) {
687 if (systemProperties
!= null ?
!systemProperties
.equals(that
.systemProperties
)
688 : that
.systemProperties
!= null) {
691 if (betaSettings
!= null ?
!betaSettings
.equals(that
.betaSettings
) : that
.betaSettings
!= null) {
694 if (healthCheck
!= null ?
!healthCheck
.equals(that
.healthCheck
)
695 : that
.healthCheck
!= null) {
698 if (resources
!= null ?
!resources
.equals(that
.resources
) : that
.resources
!= null) {
701 if (network
!= null ?
!network
.equals(that
.network
) : that
.network
!= null) {
704 if (userPermissions
!= null ?
!userPermissions
.equals(that
.userPermissions
)
705 : that
.userPermissions
!= null) {
708 if (apiConfig
!= null ?
!apiConfig
.equals(that
.apiConfig
)
709 : that
.apiConfig
!= null) {
712 if (apiEndpointIds
!= null ?
!apiEndpointIds
.equals(that
.apiEndpointIds
)
713 : that
.apiEndpointIds
!= null) {
716 if (pagespeed
!= null ?
!pagespeed
.equals(that
.pagespeed
) : that
.pagespeed
!= null) {
719 if (classLoaderConfig
!= null ?
!classLoaderConfig
.equals(that
.classLoaderConfig
) :
720 that
.classLoaderConfig
!= null) {
723 if (urlStreamHandlerType
!= null ?
!urlStreamHandlerType
.equals(that
.urlStreamHandlerType
) :
724 that
.urlStreamHandlerType
!= null) {
727 if (useGoogleConnectorJ
!= that
.useGoogleConnectorJ
) {
735 public int hashCode() {
736 int result
= systemProperties
!= null ? systemProperties
.hashCode() : 0;
737 result
= 31 * result
+ (envVariables
!= null ? envVariables
.hashCode() : 0);
738 result
= 31 * result
+ (userPermissions
!= null ? userPermissions
.hashCode() : 0);
739 result
= 31 * result
+ (appId
!= null ? appId
.hashCode() : 0);
740 result
= 31 * result
+ (majorVersionId
!= null ? majorVersionId
.hashCode() : 0);
741 result
= 31 * result
+ (sourceLanguage
!= null ? sourceLanguage
.hashCode() : 0);
742 result
= 31 * result
+ (module
!= null ? module
.hashCode() : 0);
743 result
= 31 * result
+ (instanceClass
!= null ? instanceClass
.hashCode() : 0);
744 result
= 31 * result
+ automaticScaling
.hashCode();
745 result
= 31 * result
+ manualScaling
.hashCode();
746 result
= 31 * result
+ basicScaling
.hashCode();
747 result
= 31 * result
+ (sslEnabled ?
1 : 0);
748 result
= 31 * result
+ (useSessions ?
1 : 0);
749 result
= 31 * result
+ (asyncSessionPersistence ?
1 : 0);
751 31 * result
+ (asyncSessionPersistenceQueueName
!= null ? asyncSessionPersistenceQueueName
753 result
= 31 * result
+ (staticFileIncludes
!= null ? staticFileIncludes
.hashCode() : 0);
754 result
= 31 * result
+ (staticFileExcludes
!= null ? staticFileExcludes
.hashCode() : 0);
755 result
= 31 * result
+ (resourceFileIncludes
!= null ? resourceFileIncludes
.hashCode() : 0);
756 result
= 31 * result
+ (resourceFileExcludes
!= null ? resourceFileExcludes
.hashCode() : 0);
757 result
= 31 * result
+ (staticIncludePattern
!= null ? staticIncludePattern
.hashCode() : 0);
758 result
= 31 * result
+ (staticExcludePattern
!= null ? staticExcludePattern
.hashCode() : 0);
759 result
= 31 * result
+ (resourceIncludePattern
!= null ? resourceIncludePattern
.hashCode() : 0);
760 result
= 31 * result
+ (resourceExcludePattern
!= null ? resourceExcludePattern
.hashCode() : 0);
761 result
= 31 * result
+ (publicRoot
!= null ? publicRoot
.hashCode() : 0);
762 result
= 31 * result
+ (appRoot
!= null ? appRoot
.hashCode() : 0);
763 result
= 31 * result
+ (inboundServices
!= null ? inboundServices
.hashCode() : 0);
764 result
= 31 * result
+ (precompilationEnabled ?
1 : 0);
765 result
= 31 * result
+ (adminConsolePages
!= null ? adminConsolePages
.hashCode() : 0);
766 result
= 31 * result
+ (errorHandlers
!= null ? errorHandlers
.hashCode() : 0);
767 result
= 31 * result
+ (threadsafe ?
1 : 0);
768 result
= 31 * result
+ (autoIdPolicy
!= null ? autoIdPolicy
.hashCode() : 0);
769 result
= 31 * result
+ (threadsafeValueProvided ?
1 : 0);
770 result
= 31 * result
+ (codeLock ?
1 : 0);
771 result
= 31 * result
+ (apiConfig
!= null ? apiConfig
.hashCode() : 0);
772 result
= 31 * result
+ (apiEndpointIds
!= null ? apiEndpointIds
.hashCode() : 0);
773 result
= 31 * result
+ (pagespeed
!= null ? pagespeed
.hashCode() : 0);
774 result
= 31 * result
+ (classLoaderConfig
!= null ? classLoaderConfig
.hashCode() : 0);
775 result
= 31 * result
+ (urlStreamHandlerType
!= null ? urlStreamHandlerType
.hashCode() : 0);
776 result
= 31 * result
+ (useGoogleConnectorJ
.hashCode());
777 result
= 31 * result
+ (betaSettings
!= null ? betaSettings
.hashCode() : 0);
778 result
= 31 * result
+ (healthCheck
!= null ? healthCheck
.hashCode() : 0);
779 result
= 31 * result
+ (resources
!= null ? resources
.hashCode() : 0);
780 result
= 31 * result
+ (network
!= null ? network
.hashCode() : 0);
784 public boolean includesResource(String path
) {
785 if (resourceIncludePattern
== null) {
786 if (resourceFileIncludes
.size() == 0) {
787 resourceIncludePattern
= Pattern
.compile(".*");
789 resourceIncludePattern
= Pattern
.compile(makeRegexp(resourceFileIncludes
));
792 if (resourceExcludePattern
== null && resourceFileExcludes
.size() > 0) {
793 resourceExcludePattern
= Pattern
.compile(makeRegexp(resourceFileExcludes
));
796 return includes(path
, resourceIncludePattern
, resourceExcludePattern
);
799 public boolean includesStatic(String path
) {
800 if (staticIncludePattern
== null) {
801 if (staticFileIncludes
.size() == 0) {
803 if (publicRoot
.length() > 0) {
804 staticRoot
= publicRoot
+ "/**";
808 staticIncludePattern
= Pattern
.compile(
809 makeRegexp(Collections
.singletonList(staticRoot
)));
811 List
<String
> patterns
= new ArrayList
<String
>();
812 for (StaticFileInclude include
: staticFileIncludes
) {
813 patterns
.add(include
.getPattern());
815 staticIncludePattern
= Pattern
.compile(makeRegexp(patterns
));
818 if (staticExcludePattern
== null && staticFileExcludes
.size() > 0) {
819 staticExcludePattern
= Pattern
.compile(makeRegexp(staticFileExcludes
));
822 return includes(path
, staticIncludePattern
, staticExcludePattern
);
826 * Tests whether {@code path} is covered by the pattern {@code includes}
827 * while not being blocked by matching {@code excludes}.
829 * @param path a URL to test
830 * @param includes a non-{@code null} pattern for included URLs
831 * @param excludes a pattern for exclusion, or {@code null} to not exclude
832 * anything from the {@code includes} set.
834 public boolean includes(String path
, Pattern includes
, Pattern excludes
) {
835 assert(includes
!= null);
836 if (!includes
.matcher(path
).matches()) {
839 if (excludes
!= null && excludes
.matcher(path
).matches()) {
845 public String
makeRegexp(List
<String
> patterns
) {
846 StringBuilder builder
= new StringBuilder();
847 boolean first
= true;
848 for (String item
: patterns
) {
855 while (item
.charAt(0) == '/') {
856 item
= item
.substring(1);
860 if (appRoot
!= null) {
861 builder
.append(makeFileRegex(appRoot
));
864 builder
.append(makeFileRegex(item
));
867 return builder
.toString();
871 * Helper method to translate from appengine-web.xml "file globs" to
872 * proper regular expressions as used in app.yaml.
874 * @param fileGlob the glob to translate
875 * @return the regular expression string matching the input {@code file} pattern.
877 static String
makeFileRegex(String fileGlob
) {
878 fileGlob
= fileGlob
.replaceAll("([^A-Za-z0-9\\-_/])", "\\\\$1");
879 fileGlob
= fileGlob
.replaceAll("\\\\\\*\\\\\\*", ".*");
880 fileGlob
= fileGlob
.replaceAll("\\\\\\*", "[^/]*");
884 * Sets the application root directory, as a prefix for the regexps in
885 * {@link #includeResourcePattern(String)} and friends. This is needed
886 * because we want to match complete filenames relative to root.
890 public void setSourcePrefix(String appRoot
) {
891 this.appRoot
= appRoot
;
892 this.resourceIncludePattern
= null;
893 this.resourceExcludePattern
= null;
894 this.staticIncludePattern
= null;
895 this.staticExcludePattern
= null;
898 public String
getSourcePrefix() {
903 * Represents a {@link java.security.Permission} that needs to be
904 * granted to user code.
906 private static class UserPermission
{
907 private final String className
;
908 private final String name
;
909 private final String actions
;
911 private boolean hasHashCode
= false;
912 private int hashCode
;
914 public UserPermission(String className
, String name
, String actions
) {
915 this.className
= className
;
917 this.actions
= actions
;
920 public String
getClassName() {
924 public String
getName() {
928 public String
getActions() {
933 public int hashCode() {
938 int hash
= className
.hashCode();
939 hash
= 31 * hash
+ name
.hashCode();
940 if (actions
!= null) {
941 hash
= 31 * hash
+ actions
.hashCode();
950 public boolean equals(Object obj
) {
951 if (obj
instanceof UserPermission
) {
952 UserPermission perm
= (UserPermission
) obj
;
953 if (className
.equals(perm
.className
) && name
.equals(perm
.name
)) {
954 if (actions
== null ? perm
.actions
== null : actions
.equals(perm
.actions
)) {
964 * Represents an <include> element within the
965 * <static-files> element. Currently this includes both a
966 * pattern and an optional expiration time specification.
968 public static class StaticFileInclude
{
969 private final String pattern
;
970 private final String expiration
;
971 private final Map
<String
, String
> httpHeaders
;
973 public StaticFileInclude(String pattern
, String expiration
) {
974 this.pattern
= pattern
;
975 this.expiration
= expiration
;
976 this.httpHeaders
= new LinkedHashMap
<>();
979 public String
getPattern() {
983 public Pattern
getRegularExpression() {
984 return Pattern
.compile(makeFileRegex(pattern
));
987 public String
getExpiration() {
991 public Map
<String
, String
> getHttpHeaders() {
996 public int hashCode() {
997 return Objects
.hash(pattern
, expiration
, httpHeaders
);
1001 public boolean equals(Object obj
) {
1002 if (!(obj
instanceof StaticFileInclude
)) {
1006 StaticFileInclude other
= (StaticFileInclude
) obj
;
1008 if (pattern
!= null) {
1009 if (!pattern
.equals(other
.pattern
)) {
1013 if (other
.pattern
!= null) {
1018 if (expiration
!= null) {
1019 if (!expiration
.equals(other
.expiration
)) {
1023 if (other
.expiration
!= null) {
1028 if (httpHeaders
!= null) {
1029 if (!httpHeaders
.equals(other
.httpHeaders
)) {
1033 if (other
.httpHeaders
!= null) {
1042 public static class AdminConsolePage
{
1043 private final String name
;
1044 private final String url
;
1046 public AdminConsolePage(String name
, String url
) {
1051 public String
getName() {
1055 public String
getUrl() {
1060 public int hashCode() {
1061 final int prime
= 31;
1063 result
= prime
* result
+ ((name
== null) ?
0 : name
.hashCode());
1064 result
= prime
* result
+ ((url
== null) ?
0 : url
.hashCode());
1069 public boolean equals(Object obj
) {
1070 if (this == obj
) return true;
1071 if (obj
== null) return false;
1072 if (getClass() != obj
.getClass()) return false;
1073 AdminConsolePage other
= (AdminConsolePage
) obj
;
1075 if (other
.name
!= null) return false;
1076 } else if (!name
.equals(other
.name
)) return false;
1078 if (other
.url
!= null) return false;
1079 } else if (!url
.equals(other
.url
)) return false;
1085 * Represents an <error-handler> element. Currently this includes both
1086 * a file name and an optional error code.
1088 public static class ErrorHandler
{
1089 private final String file
;
1090 private final String errorCode
;
1092 public ErrorHandler(String file
, String errorCode
) {
1094 this.errorCode
= errorCode
;
1097 public String
getFile() {
1101 public String
getErrorCode() {
1106 public int hashCode() {
1107 final int prime
= 31;
1109 result
= prime
* result
+ ((file
== null) ?
0 : file
.hashCode());
1110 result
= prime
* result
+
1111 ((errorCode
== null) ?
0 : errorCode
.hashCode());
1116 public boolean equals(Object obj
) {
1117 if (!(obj
instanceof ErrorHandler
)) {
1121 ErrorHandler handler
= (ErrorHandler
) obj
;
1122 if (!file
.equals(handler
.file
)) {
1126 if (errorCode
== null) {
1127 if (handler
.errorCode
!= null) {
1131 if (!errorCode
.equals(handler
.errorCode
)) {
1141 * Represents an <api-config> element. This is a singleton specifying
1142 * url-pattern and servlet-class for the api config server.
1144 public static class ApiConfig
{
1145 private final String servletClass
;
1146 private final String url
;
1148 public ApiConfig(String servletClass
, String url
) {
1149 this.servletClass
= servletClass
;
1153 public String
getservletClass() {
1154 return servletClass
;
1157 public String
getUrl() {
1162 public int hashCode() {
1163 final int prime
= 31;
1165 result
= prime
* result
+ ((servletClass
== null) ?
0 : servletClass
.hashCode());
1166 result
= prime
* result
+ ((url
== null) ?
0 : url
.hashCode());
1171 public boolean equals(Object obj
) {
1172 if (this == obj
) { return true; }
1173 if (obj
== null) { return false; }
1174 if (getClass() != obj
.getClass()) { return false; }
1175 ApiConfig other
= (ApiConfig
) obj
;
1176 if (servletClass
== null) {
1177 if (other
.servletClass
!= null) { return false; }
1178 } else if (!servletClass
.equals(other
.servletClass
)) { return false; }
1180 if (other
.url
!= null) { return false; }
1181 } else if (!url
.equals(other
.url
)) { return false; }
1186 public String
toString() {
1187 return "ApiConfig{servletClass=\"" + servletClass
+ "\", url=\"" + url
+ "\"}";
1192 * Holder for automatic settings.
1194 public static class AutomaticScaling
{
1195 private static final AutomaticScaling EMPTY_SETTINGS
= new AutomaticScaling();
1197 public static final String AUTOMATIC
= "automatic";
1198 private String minPendingLatency
;
1199 private String maxPendingLatency
;
1200 private String minIdleInstances
;
1201 private String maxIdleInstances
;
1202 private String maxConcurrentRequests
;
1204 private Integer minNumInstances
;
1205 private Integer maxNumInstances
;
1206 private Integer coolDownPeriodSec
;
1207 private CpuUtilization cpuUtilization
;
1209 public String
getMinPendingLatency() {
1210 return minPendingLatency
;
1214 * Sets minPendingLatency. Normalizes empty and null inputs to null.
1216 public void setMinPendingLatency(String minPendingLatency
) {
1217 this.minPendingLatency
= StringUtil
.toNullIfEmptyOrWhitespace(minPendingLatency
);
1220 public String
getMaxPendingLatency() {
1221 return maxPendingLatency
;
1225 * Sets maxPendingLatency. Normalizes empty and null inputs to null.
1227 public void setMaxPendingLatency(String maxPendingLatency
) {
1228 this.maxPendingLatency
= StringUtil
.toNullIfEmptyOrWhitespace(maxPendingLatency
);
1231 public String
getMinIdleInstances() {
1232 return minIdleInstances
;
1236 * Sets minIdleInstances. Normalizes empty and null inputs to null.
1238 public void setMinIdleInstances(String minIdleInstances
) {
1239 this.minIdleInstances
= StringUtil
.toNullIfEmptyOrWhitespace(minIdleInstances
);
1242 public String
getMaxIdleInstances() {
1243 return maxIdleInstances
;
1247 * Sets maxIdleInstances. Normalizes empty and null inputs to null.
1249 public void setMaxIdleInstances(String maxIdleInstances
) {
1250 this.maxIdleInstances
= StringUtil
.toNullIfEmptyOrWhitespace(maxIdleInstances
);
1253 public boolean isEmpty() {
1254 return this.equals(EMPTY_SETTINGS
);
1257 public String
getMaxConcurrentRequests() {
1258 return maxConcurrentRequests
;
1262 * Sets maxConcurrentRequests. Normalizes empty and null inputs to null.
1264 public void setMaxConcurrentRequests(String maxConcurrentRequests
) {
1265 this.maxConcurrentRequests
= StringUtil
.toNullIfEmptyOrWhitespace(maxConcurrentRequests
);
1268 public Integer
getMinNumInstances() {
1269 return minNumInstances
;
1272 public void setMinNumInstances(Integer minNumInstances
) {
1273 this.minNumInstances
= minNumInstances
;
1276 public Integer
getMaxNumInstances() {
1277 return maxNumInstances
;
1280 public void setMaxNumInstances(Integer maxNumInstances
) {
1281 this.maxNumInstances
= maxNumInstances
;
1284 public Integer
getCoolDownPeriodSec() {
1285 return coolDownPeriodSec
;
1288 public void setCoolDownPeriodSec(Integer coolDownPeriodSec
) {
1289 this.coolDownPeriodSec
= coolDownPeriodSec
;
1292 public CpuUtilization
getCpuUtilization() {
1293 return cpuUtilization
;
1296 public void setCpuUtilization(CpuUtilization cpuUtilization
) {
1297 this.cpuUtilization
= cpuUtilization
;
1301 public int hashCode() {
1302 return Objects
.hash(maxPendingLatency
, minPendingLatency
, maxIdleInstances
,
1303 minIdleInstances
, maxConcurrentRequests
, minNumInstances
,
1304 maxNumInstances
, coolDownPeriodSec
, cpuUtilization
);
1308 public boolean equals(Object obj
) {
1315 if (getClass() != obj
.getClass()) {
1318 AutomaticScaling other
= (AutomaticScaling
) obj
;
1319 return Objects
.equals(maxPendingLatency
, other
.maxPendingLatency
)
1320 && Objects
.equals(minPendingLatency
, other
.minPendingLatency
)
1321 && Objects
.equals(maxIdleInstances
, other
.maxIdleInstances
)
1322 && Objects
.equals(minIdleInstances
, other
.minIdleInstances
)
1323 && Objects
.equals(maxConcurrentRequests
, other
.maxConcurrentRequests
)
1324 && Objects
.equals(minNumInstances
, other
.minNumInstances
)
1325 && Objects
.equals(maxNumInstances
, other
.maxNumInstances
)
1326 && Objects
.equals(coolDownPeriodSec
, other
.coolDownPeriodSec
)
1327 && Objects
.equals(cpuUtilization
, other
.cpuUtilization
);
1331 public String
toString() {
1332 return "AutomaticScaling [minPendingLatency=" + minPendingLatency
1333 + ", maxPendingLatency=" + maxPendingLatency
1334 + ", minIdleInstances=" + minIdleInstances
1335 + ", maxIdleInstances=" + maxIdleInstances
1336 + ", maxConcurrentRequests=" + maxConcurrentRequests
1337 + ", minNumInstances=" + minNumInstances
1338 + ", maxNumInstances=" + maxNumInstances
1339 + ", coolDownPeriodSec=" + coolDownPeriodSec
1340 + ", cpuUtilization=" + cpuUtilization
+ "]";
1345 * Holder for CPU utilization.
1347 public static class CpuUtilization
{
1348 private static final CpuUtilization EMPTY_SETTINGS
= new CpuUtilization();
1349 private Double targetUtilization
;
1350 private Integer aggregationWindowLengthSec
;
1352 public Double
getTargetUtilization() {
1353 return targetUtilization
;
1356 public void setTargetUtilization(Double targetUtilization
) {
1357 this.targetUtilization
= targetUtilization
;
1360 public Integer
getAggregationWindowLengthSec() {
1361 return aggregationWindowLengthSec
;
1364 public void setAggregationWindowLengthSec(Integer aggregationWindowLengthSec
) {
1365 this.aggregationWindowLengthSec
= aggregationWindowLengthSec
;
1368 public boolean isEmpty() {
1369 return this.equals(EMPTY_SETTINGS
);
1373 public int hashCode() {
1374 return Objects
.hash(targetUtilization
, aggregationWindowLengthSec
);
1378 public boolean equals(Object obj
) {
1385 if (getClass() != obj
.getClass()) {
1388 CpuUtilization other
= (CpuUtilization
) obj
;
1389 return Objects
.equals(targetUtilization
, other
.targetUtilization
)
1390 && Objects
.equals(aggregationWindowLengthSec
, other
.aggregationWindowLengthSec
);
1394 public String
toString() {
1395 return "CpuUtilization [targetUtilization=" + targetUtilization
1396 + ", aggregationWindowLengthSec=" + aggregationWindowLengthSec
+ "]";
1401 * Holder for health check.
1403 public static class HealthCheck
{
1404 private static final HealthCheck EMPTY_SETTINGS
= new HealthCheck();
1406 private boolean enableHealthCheck
= true;
1407 private Integer checkIntervalSec
;
1408 private Integer timeoutSec
;
1409 private Integer unhealthyThreshold
;
1410 private Integer healthyThreshold
;
1411 private Integer restartThreshold
;
1412 private String host
;
1414 public boolean getEnableHealthCheck() {
1415 return enableHealthCheck
;
1418 * Sets enableHealthCheck.
1420 public void setEnableHealthCheck(boolean enableHealthCheck
) {
1421 this.enableHealthCheck
= enableHealthCheck
;
1424 public Integer
getCheckIntervalSec() {
1425 return checkIntervalSec
;
1428 * Sets checkIntervalSec.
1430 public void setCheckIntervalSec(Integer checkIntervalSec
) {
1431 this.checkIntervalSec
= checkIntervalSec
;
1434 public Integer
getTimeoutSec() {
1440 public void setTimeoutSec(Integer timeoutSec
) {
1441 this.timeoutSec
= timeoutSec
;
1444 public Integer
getUnhealthyThreshold() {
1445 return unhealthyThreshold
;
1449 * Sets unhealthyThreshold.
1451 public void setUnhealthyThreshold(Integer unhealthyThreshold
) {
1452 this.unhealthyThreshold
= unhealthyThreshold
;
1455 public Integer
getHealthyThreshold() {
1456 return healthyThreshold
;
1460 * Sets healthyThreshold.
1463 public void setHealthyThreshold(Integer healthyThreshold
) {
1464 this.healthyThreshold
= healthyThreshold
;
1467 public Integer
getRestartThreshold() {
1468 return restartThreshold
;
1472 * Sets restartThreshold.
1474 public void setRestartThreshold(Integer restartThreshold
) {
1475 this.restartThreshold
= restartThreshold
;
1478 public String
getHost() {
1483 * Sets host. Normalizes empty and null inputs to null.
1485 public void setHost(String host
) {
1486 this.host
= StringUtil
.toNullIfEmptyOrWhitespace(host
);
1489 public boolean isEmpty() {
1490 return this.equals(EMPTY_SETTINGS
);
1494 public int hashCode() {
1495 return Objects
.hash(enableHealthCheck
, checkIntervalSec
, timeoutSec
, unhealthyThreshold
,
1496 healthyThreshold
, restartThreshold
, host
);
1500 public boolean equals(Object obj
) {
1507 if (getClass() != obj
.getClass()) {
1510 HealthCheck other
= (HealthCheck
) obj
;
1511 return Objects
.equals(enableHealthCheck
, other
.enableHealthCheck
)
1512 && Objects
.equals(checkIntervalSec
, other
.checkIntervalSec
)
1513 && Objects
.equals(timeoutSec
, other
.timeoutSec
)
1514 && Objects
.equals(unhealthyThreshold
, other
.unhealthyThreshold
)
1515 && Objects
.equals(healthyThreshold
, other
.healthyThreshold
)
1516 && Objects
.equals(restartThreshold
, other
.restartThreshold
)
1517 && Objects
.equals(host
, other
.host
);
1521 public String
toString() {
1522 return "HealthCheck [enableHealthCheck=" + enableHealthCheck
1523 + ", checkIntervalSec=" + checkIntervalSec
1524 + ", timeoutSec=" + timeoutSec
1525 + ", unhealthyThreshold=" + unhealthyThreshold
1526 + ", healthyThreshold=" + healthyThreshold
1527 + ", restartThreshold=" + restartThreshold
1528 + ", host=" + host
+ "]";
1533 * Holder for Resources
1535 public static class Resources
{
1536 private static final Resources EMPTY_SETTINGS
= new Resources();
1540 public double getCpu() {
1544 public void setCpu(double cpu
) {
1548 private double memory_gb
;
1550 public double getMemoryGb() {
1554 public void setMemoryGb(double memory_gb
) {
1555 this.memory_gb
= memory_gb
;
1558 private int disk_size_gb
;
1560 public int getDiskSizeGb() {
1561 return disk_size_gb
;
1564 public void setDiskSizeGb(int disk_size_gb
) {
1565 this.disk_size_gb
= disk_size_gb
;
1568 public boolean isEmpty() {
1569 return this.equals(EMPTY_SETTINGS
);
1573 public int hashCode() {
1574 return Objects
.hash(cpu
, memory_gb
, disk_size_gb
);
1578 public boolean equals(Object obj
) {
1585 if (getClass() != obj
.getClass()) {
1588 Resources other
= (Resources
) obj
;
1589 return Objects
.equals(cpu
, other
.cpu
) &&
1590 Objects
.equals(memory_gb
, other
.memory_gb
) &&
1591 Objects
.equals(disk_size_gb
, other
.disk_size_gb
);
1595 public String
toString() {
1596 return "Resources [" + "cpu=" + cpu
+
1597 ", memory_gb=" + memory_gb
+
1598 ", disk_size_gb=" + disk_size_gb
+ "]";
1603 * Holder for network.
1605 public static class Network
{
1606 private static final Network EMPTY_SETTINGS
= new Network();
1608 private String instanceTag
;
1610 public String
getInstanceTag() {
1614 public void setInstanceTag(String instanceTag
) {
1615 this.instanceTag
= instanceTag
;
1618 private final List
<String
> forwardedPorts
= Lists
.newArrayList();
1620 public List
<String
> getForwardedPorts() {
1621 return Collections
.unmodifiableList(forwardedPorts
);
1624 public void addForwardedPort(String forwardedPort
) {
1625 forwardedPorts
.add(forwardedPort
);
1628 private String name
;
1630 public String
getName() {
1634 public void setName(String name
) {
1638 public boolean isEmpty() {
1639 return this.equals(EMPTY_SETTINGS
);
1643 public int hashCode() {
1644 return Objects
.hash(forwardedPorts
, instanceTag
);
1648 public boolean equals(Object obj
) {
1655 if (getClass() != obj
.getClass()) {
1658 Network other
= (Network
) obj
;
1659 return Objects
.equals(forwardedPorts
, other
.forwardedPorts
)
1660 && Objects
.equals(instanceTag
, other
.instanceTag
);
1664 public String
toString() {
1665 return "Network [forwardedPorts=" + forwardedPorts
+ ", instanceTag=" + instanceTag
+ "]";
1670 * Holder for manual settings.
1672 public static class ManualScaling
{
1673 private static final ManualScaling EMPTY_SETTINGS
= new ManualScaling();
1675 private String instances
;
1677 public String
getInstances() {
1682 * Sets instances. Normalizes empty and null inputs to null.
1684 public void setInstances(String instances
) {
1685 this.instances
= StringUtil
.toNullIfEmptyOrWhitespace(instances
);
1688 public boolean isEmpty() {
1689 return this.equals(EMPTY_SETTINGS
);
1693 public int hashCode() {
1694 return Objects
.hash(instances
);
1698 public boolean equals(Object obj
) {
1705 if (getClass() != obj
.getClass()) {
1708 ManualScaling other
= (ManualScaling
) obj
;
1709 return Objects
.equals(instances
, other
.instances
);
1713 public String
toString() {
1714 return "ManualScaling [" + "instances=" + instances
+ "]";
1719 * Holder for basic settings.
1721 public static class BasicScaling
{
1722 private static final BasicScaling EMPTY_SETTINGS
= new BasicScaling();
1724 private String maxInstances
;
1725 private String idleTimeout
;
1727 public String
getMaxInstances() {
1728 return maxInstances
;
1731 public String
getIdleTimeout() {
1736 * Sets maxInstances. Normalizes empty and null inputs to null.
1738 public void setMaxInstances(String maxInstances
) {
1739 this.maxInstances
= StringUtil
.toNullIfEmptyOrWhitespace(maxInstances
);
1743 * Sets idleTimeout. Normalizes empty and null inputs to null.
1745 public void setIdleTimeout(String idleTimeout
) {
1746 this.idleTimeout
= StringUtil
.toNullIfEmptyOrWhitespace(idleTimeout
);
1749 public boolean isEmpty() {
1750 return this.equals(EMPTY_SETTINGS
);
1754 public int hashCode() {
1755 return Objects
.hash(maxInstances
, idleTimeout
);
1759 public boolean equals(Object obj
) {
1766 if (getClass() != obj
.getClass()) {
1769 BasicScaling other
= (BasicScaling
) obj
;
1770 return Objects
.equals(maxInstances
, other
.maxInstances
)
1771 && Objects
.equals(idleTimeout
, other
.idleTimeout
);
1775 public String
toString() {
1776 return "BasicScaling [" + "maxInstances=" + maxInstances
1777 + ", idleTimeout=" + idleTimeout
+ "]";
1782 * Represents a <pagespeed> element. This is used to specify configuration for the Page
1783 * Speed Service, which can be used to automatically optimize the loading speed of app engine
1786 public static class Pagespeed
{
1787 private final List
<String
> urlBlacklist
= Lists
.newArrayList();
1788 private final List
<String
> domainsToRewrite
= Lists
.newArrayList();
1789 private final List
<String
> enabledRewriters
= Lists
.newArrayList();
1790 private final List
<String
> disabledRewriters
= Lists
.newArrayList();
1792 public void addUrlBlacklist(String url
) {
1793 urlBlacklist
.add(url
);
1796 public List
<String
> getUrlBlacklist() {
1797 return Collections
.unmodifiableList(urlBlacklist
);
1800 public void addDomainToRewrite(String domain
) {
1801 domainsToRewrite
.add(domain
);
1804 public List
<String
> getDomainsToRewrite() {
1805 return Collections
.unmodifiableList(domainsToRewrite
);
1808 public void addEnabledRewriter(String rewriter
) {
1809 enabledRewriters
.add(rewriter
);
1812 public List
<String
> getEnabledRewriters() {
1813 return Collections
.unmodifiableList(enabledRewriters
);
1816 public void addDisabledRewriter(String rewriter
) {
1817 disabledRewriters
.add(rewriter
);
1820 public List
<String
> getDisabledRewriters() {
1821 return Collections
.unmodifiableList(disabledRewriters
);
1824 public boolean isEmpty() {
1825 return urlBlacklist
.isEmpty() && domainsToRewrite
.isEmpty() && enabledRewriters
.isEmpty()
1826 && disabledRewriters
.isEmpty();
1830 public int hashCode() {
1831 return Objects
.hash(urlBlacklist
, domainsToRewrite
, enabledRewriters
, disabledRewriters
);
1835 public boolean equals(Object obj
) {
1842 if (getClass() != obj
.getClass()) {
1845 Pagespeed other
= (Pagespeed
) obj
;
1846 return Objects
.equals(urlBlacklist
, other
.urlBlacklist
)
1847 && Objects
.equals(domainsToRewrite
, other
.domainsToRewrite
)
1848 && Objects
.equals(enabledRewriters
, other
.enabledRewriters
)
1849 && Objects
.equals(disabledRewriters
, other
.disabledRewriters
);
1853 public String
toString() {
1854 return "Pagespeed [urlBlacklist=" + urlBlacklist
+ ", domainsToRewrite=" + domainsToRewrite
1855 + ", enabledRewriters=" + enabledRewriters
+ ", disabledRewriters=" + disabledRewriters
1860 public static class ClassLoaderConfig
{
1861 private final List
<PrioritySpecifierEntry
> entries
= Lists
.newArrayList();
1863 public void add(PrioritySpecifierEntry entry
) {
1867 public List
<PrioritySpecifierEntry
> getEntries() {
1872 public int hashCode() {
1873 final int prime
= 31;
1875 result
= prime
* result
+ ((entries
== null) ?
0 : entries
.hashCode());
1880 public boolean equals(Object obj
) {
1881 if (this == obj
) return true;
1882 if (obj
== null) return false;
1883 if (getClass() != obj
.getClass()) return false;
1884 ClassLoaderConfig other
= (ClassLoaderConfig
) obj
;
1885 if (entries
== null) {
1886 if (other
.entries
!= null) return false;
1887 } else if (!entries
.equals(other
.entries
)) return false;
1892 public String
toString() {
1893 return "ClassLoaderConfig{entries=\"" + entries
+ "\"}";
1897 public static class PrioritySpecifierEntry
{
1898 private String filename
;
1899 private Double priority
;
1901 private void checkNotAlreadySet() {
1902 if (filename
!= null) {
1903 throw new AppEngineConfigException("Found more that one file name matching tag. "
1904 + "Only one of 'filename' attribute allowed.");
1908 public String
getFilename() {
1912 public void setFilename(String filename
) {
1913 checkNotAlreadySet();
1914 this.filename
= filename
;
1917 public Double
getPriority() {
1921 public double getPriorityValue() {
1922 if (priority
== null) {
1928 public void setPriority(String priority
) {
1929 if (this.priority
!= null) {
1930 throw new AppEngineConfigException("The 'priority' tag may only be specified once.");
1933 if (priority
== null) {
1934 this.priority
= null;
1938 this.priority
= Double
.parseDouble(priority
);
1941 public void checkClassLoaderConfig() {
1942 if (filename
== null) {
1943 throw new AppEngineConfigException("Must have a filename attribute.");
1948 public int hashCode() {
1949 final int prime
= 31;
1951 result
= prime
* result
+ ((filename
== null) ?
0 : filename
.hashCode());
1952 result
= prime
* result
+ ((priority
== null) ?
0 : priority
.hashCode());
1957 public boolean equals(Object obj
) {
1958 if (this == obj
) return true;
1959 if (obj
== null) return false;
1960 if (getClass() != obj
.getClass()) return false;
1961 PrioritySpecifierEntry other
= (PrioritySpecifierEntry
) obj
;
1962 if (filename
== null) {
1963 if (other
.filename
!= null) return false;
1964 } else if (!filename
.equals(other
.filename
)) return false;
1965 if (priority
== null) {
1966 if (other
.priority
!= null) return false;
1967 } else if (!priority
.equals(other
.priority
)) return false;
1972 public String
toString() {
1973 return "PrioritySpecifierEntry{filename=\"" + filename
+ "\", priority=\"" + priority
+ "\"}";