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
{
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
>();
133 * @return An unmodifiable map whose entries correspond to the
134 * system properties defined in appengine-web.xml.
136 public Map
<String
, String
> getSystemProperties() {
137 return Collections
.unmodifiableMap(systemProperties
);
140 public void addSystemProperty(String key
, String value
) {
141 systemProperties
.put(key
, value
);
145 * @return An unmodifiable map whose entires correspond to the
146 * vm settings defined in appengine-web.xml.
148 public Map
<String
, String
> getBetaSettings() {
149 return Collections
.unmodifiableMap(betaSettings
);
152 public void addBetaSetting(String key
, String value
) {
153 betaSettings
.put(key
, value
);
156 public HealthCheck
getHealthCheck() {
160 public Resources
getResources() {
164 public Network
getNetwork() {
169 * @return An unmodifiable map whose entires correspond to the
170 * environment variables defined in appengine-web.xml.
172 public Map
<String
, String
> getEnvironmentVariables() {
173 return Collections
.unmodifiableMap(envVariables
);
176 public void addEnvironmentVariable(String key
, String value
) {
177 envVariables
.put(key
, value
);
180 public String
getAppId() {
184 public void setAppId(String appId
) {
188 public String
getMajorVersionId() {
189 return majorVersionId
;
192 public void setMajorVersionId(String majorVersionId
) {
193 this.majorVersionId
= majorVersionId
;
196 public String
getSourceLanguage() {
197 return this.sourceLanguage
;
200 public void setSourceLanguage(String sourceLanguage
) {
201 this.sourceLanguage
= sourceLanguage
;
204 public String
getModule() {
209 * Sets instanceClass (aka class in the xml/yaml files). Normalizes empty and null
212 public void setInstanceClass(String instanceClass
) {
213 this.instanceClass
= StringUtil
.toNullIfEmptyOrWhitespace(instanceClass
);
216 public String
getInstanceClass() {
217 return instanceClass
;
220 public AutomaticScaling
getAutomaticScaling() {
221 return automaticScaling
;
224 public ManualScaling
getManualScaling() {
225 return manualScaling
;
228 public BasicScaling
getBasicScaling() {
232 public ScalingType
getScalingType() {
233 if (!getBasicScaling().isEmpty()) {
234 return ScalingType
.BASIC
;
235 } else if (!getManualScaling().isEmpty()) {
236 return ScalingType
.MANUAL
;
238 return ScalingType
.AUTOMATIC
;
242 public void setModule(String module
) {
243 this.module
= module
;
246 public void setSslEnabled(boolean ssl
) {
250 public boolean getSslEnabled() {
254 public void setSessionsEnabled(boolean sessions
) {
255 useSessions
= sessions
;
258 public boolean getSessionsEnabled() {
262 public void setAsyncSessionPersistence(boolean asyncSessionPersistence
) {
263 this.asyncSessionPersistence
= asyncSessionPersistence
;
266 public boolean getAsyncSessionPersistence() {
267 return asyncSessionPersistence
;
270 public void setAsyncSessionPersistenceQueueName(String asyncSessionPersistenceQueueName
) {
271 this.asyncSessionPersistenceQueueName
= asyncSessionPersistenceQueueName
;
274 public String
getAsyncSessionPersistenceQueueName() {
275 return asyncSessionPersistenceQueueName
;
278 public List
<StaticFileInclude
> getStaticFileIncludes() {
279 return staticFileIncludes
;
282 public List
<String
> getStaticFileExcludes() {
283 return staticFileExcludes
;
286 public StaticFileInclude
includeStaticPattern(String pattern
, String expiration
) {
287 staticIncludePattern
= null;
288 StaticFileInclude staticFileInclude
= new StaticFileInclude(pattern
, expiration
);
289 staticFileIncludes
.add(staticFileInclude
);
290 return staticFileInclude
;
293 public void excludeStaticPattern(String url
) {
294 staticExcludePattern
= null;
295 staticFileExcludes
.add(url
);
298 public List
<String
> getResourcePatterns() {
299 return resourceFileIncludes
;
302 public List
<String
> getResourceFileExcludes() {
303 return resourceFileExcludes
;
306 public void includeResourcePattern(String url
) {
307 resourceExcludePattern
= null;
308 resourceFileIncludes
.add(url
);
311 public void excludeResourcePattern(String url
) {
312 resourceIncludePattern
= null;
313 resourceFileExcludes
.add(url
);
316 public void addUserPermission(String className
, String name
, String actions
) {
317 if (className
.startsWith("java.")) {
318 throw new AppEngineConfigException("Cannot specify user-permissions for " +
319 "classes in java.* packages.");
322 userPermissions
.add(new UserPermission(className
, name
, actions
));
325 public Permissions
getUserPermissions() {
326 Permissions permissions
= new Permissions();
327 for (UserPermission permission
: userPermissions
) {
328 permissions
.add(new UnresolvedPermission(permission
.getClassName(),
329 permission
.getName(),
330 permission
.getActions(),
333 permissions
.setReadOnly();
337 public void setPublicRoot(String root
) {
338 if (root
.indexOf('*') != -1) {
339 throw new AppEngineConfigException("public-root cannot contain wildcards");
341 if (root
.endsWith("/")) {
342 root
= root
.substring(0, root
.length() - 1);
344 if (root
.length() > 0 && !root
.startsWith("/")) {
347 staticIncludePattern
= null;
351 public String
getPublicRoot() {
355 public void addInboundService(String service
) {
356 inboundServices
.add(service
);
359 public Set
<String
> getInboundServices() {
360 return inboundServices
;
363 public boolean getPrecompilationEnabled() {
364 return precompilationEnabled
;
367 public void setPrecompilationEnabled(boolean precompilationEnabled
) {
368 this.precompilationEnabled
= precompilationEnabled
;
371 public boolean getWarmupRequestsEnabled() {
372 return inboundServices
.contains(WARMUP_SERVICE
);
375 public void setWarmupRequestsEnabled(boolean warmupRequestsEnabled
) {
376 if (warmupRequestsEnabled
) {
377 inboundServices
.add(WARMUP_SERVICE
);
379 inboundServices
.remove(WARMUP_SERVICE
);
383 public List
<AdminConsolePage
> getAdminConsolePages() {
384 return Collections
.unmodifiableList(adminConsolePages
);
387 public void addAdminConsolePage(AdminConsolePage page
) {
388 adminConsolePages
.add(page
);
391 public List
<ErrorHandler
> getErrorHandlers() {
392 return Collections
.unmodifiableList(errorHandlers
);
395 public void addErrorHandler(ErrorHandler handler
) {
396 errorHandlers
.add(handler
);
399 public boolean getThreadsafe() {
403 public boolean getThreadsafeValueProvided() {
404 return threadsafeValueProvided
;
407 public void setThreadsafe(boolean threadsafe
) {
408 this.threadsafe
= threadsafe
;
409 this.threadsafeValueProvided
= true;
412 public void setAutoIdPolicy(String policy
) {
413 autoIdPolicy
= policy
;
416 public String
getAutoIdPolicy() {
420 public boolean getCodeLock() {
424 public void setCodeLock(boolean codeLock
) {
425 this.codeLock
= codeLock
;
428 public void setUseVm(boolean useVm
) {
432 public boolean getUseVm() {
436 public ApiConfig
getApiConfig() {
440 public void setApiConfig(ApiConfig config
) {
444 public ClassLoaderConfig
getClassLoaderConfig() {
445 return classLoaderConfig
;
448 public void setClassLoaderConfig(ClassLoaderConfig classLoaderConfig
) {
449 if (this.classLoaderConfig
!= null) {
450 throw new AppEngineConfigException("class-loader-config may only be specified once.");
452 this.classLoaderConfig
= classLoaderConfig
;
455 public String
getUrlStreamHandlerType() {
456 return urlStreamHandlerType
;
459 public void setUrlStreamHandlerType(String urlStreamHandlerType
) {
460 if (this.classLoaderConfig
!= null) {
461 throw new AppEngineConfigException("url-stream-handler may only be specified once.");
463 if (!URL_HANDLER_URLFETCH
.equals(urlStreamHandlerType
)
464 && !URL_HANDLER_NATIVE
.equals(urlStreamHandlerType
)) {
465 throw new AppEngineConfigException(
466 "url-stream-handler must be " + URL_HANDLER_URLFETCH
+ " or " + URL_HANDLER_NATIVE
+
467 " given " + urlStreamHandlerType
);
469 this.urlStreamHandlerType
= urlStreamHandlerType
;
473 * Returns true if {@code url} matches one of the servlets or servlet
474 * filters listed in this web.xml that has api-endpoint set to true.
476 public boolean isApiEndpoint(String id
) {
477 return apiEndpointIds
.contains(id
);
480 public void addApiEndpoint(String id
) {
481 apiEndpointIds
.add(id
);
484 public Pagespeed
getPagespeed() {
488 public void setPagespeed(Pagespeed pagespeed
) {
489 this.pagespeed
= pagespeed
;
492 public void setUseGoogleConnectorJ(boolean useGoogleConnectorJ
) {
493 if (useGoogleConnectorJ
) {
494 this.useGoogleConnectorJ
= UseGoogleConnectorJ
.TRUE
;
496 this.useGoogleConnectorJ
= UseGoogleConnectorJ
.FALSE
;
500 public UseGoogleConnectorJ
getUseGoogleConnectorJ() {
501 return useGoogleConnectorJ
;
505 public String
toString() {
506 return "AppEngineWebXml{" +
507 "systemProperties=" + systemProperties
+
508 ", envVariables=" + envVariables
+
509 ", userPermissions=" + userPermissions
+
510 ", appId='" + appId
+ '\'' +
511 ", majorVersionId='" + majorVersionId
+ '\'' +
512 ", sourceLanguage='" + sourceLanguage
+ '\'' +
513 ", module='" + module
+ '\'' +
514 ", instanceClass='" + instanceClass
+ '\'' +
515 ", automaticScaling=" + automaticScaling
+
516 ", manualScaling=" + manualScaling
+
517 ", basicScaling=" + basicScaling
+
518 ", healthCheck=" + healthCheck
+
519 ", resources=" + resources
+
520 ", network=" + network
+
521 ", sslEnabled=" + sslEnabled
+
522 ", useSessions=" + useSessions
+
523 ", asyncSessionPersistence=" + asyncSessionPersistence
+
524 ", asyncSessionPersistenceQueueName='" + asyncSessionPersistenceQueueName
+ '\'' +
525 ", staticFileIncludes=" + staticFileIncludes
+
526 ", staticFileExcludes=" + staticFileExcludes
+
527 ", resourceFileIncludes=" + resourceFileIncludes
+
528 ", resourceFileExcludes=" + resourceFileExcludes
+
529 ", staticIncludePattern=" + staticIncludePattern
+
530 ", staticExcludePattern=" + staticExcludePattern
+
531 ", resourceIncludePattern=" + resourceIncludePattern
+
532 ", resourceExcludePattern=" + resourceExcludePattern
+
533 ", publicRoot='" + publicRoot
+ '\'' +
534 ", appRoot='" + appRoot
+ '\'' +
535 ", inboundServices=" + inboundServices
+
536 ", precompilationEnabled=" + precompilationEnabled
+
537 ", adminConsolePages=" + adminConsolePages
+
538 ", errorHandlers=" + errorHandlers
+
539 ", threadsafe=" + threadsafe
+
540 ", threadsafeValueProvided=" + threadsafeValueProvided
+
541 ", autoIdPolicy=" + autoIdPolicy
+
542 ", codeLock=" + codeLock
+
543 ", apiConfig=" + apiConfig
+
544 ", apiEndpointIds=" + apiEndpointIds
+
545 ", pagespeed=" + pagespeed
+
546 ", classLoaderConfig=" + classLoaderConfig
+
547 ", urlStreamHandlerType=" +
548 (urlStreamHandlerType
== null ? URL_HANDLER_URLFETCH
: urlStreamHandlerType
) +
549 ", useGoogleConnectorJ=" + useGoogleConnectorJ
+
554 public boolean equals(Object o
) {
558 if (o
== null || getClass() != o
.getClass()) {
562 AppEngineWebXml that
= (AppEngineWebXml
) o
;
564 if (asyncSessionPersistence
!= that
.asyncSessionPersistence
) {
567 if (precompilationEnabled
!= that
.precompilationEnabled
) {
570 if (sslEnabled
!= that
.sslEnabled
) {
573 if (threadsafe
!= that
.threadsafe
) {
576 if (threadsafeValueProvided
!= that
.threadsafeValueProvided
) {
579 if (autoIdPolicy
!= null ?
!autoIdPolicy
.equals(that
.autoIdPolicy
)
580 : that
.autoIdPolicy
!= null) {
583 if (codeLock
!= that
.codeLock
) {
586 if (useSessions
!= that
.useSessions
) {
589 if (adminConsolePages
!= null ?
!adminConsolePages
.equals(that
.adminConsolePages
)
590 : that
.adminConsolePages
!= null) {
593 if (appId
!= null ?
!appId
.equals(that
.appId
) : that
.appId
!= null) {
596 if (majorVersionId
!= null ?
!majorVersionId
.equals(that
.majorVersionId
)
597 : that
.majorVersionId
!= null) {
600 if (module
!= null ?
!module
.equals(that
.module
) : that
.module
!= null) {
603 if (instanceClass
!= null ?
!instanceClass
.equals(that
.instanceClass
)
604 : that
.instanceClass
!= null) {
607 if (!automaticScaling
.equals(that
.automaticScaling
)) {
610 if (!manualScaling
.equals(that
.manualScaling
)) {
613 if (!basicScaling
.equals(that
.basicScaling
)) {
616 if (appRoot
!= null ?
!appRoot
.equals(that
.appRoot
) : that
.appRoot
!= null) {
619 if (asyncSessionPersistenceQueueName
!= null ?
!asyncSessionPersistenceQueueName
620 .equals(that
.asyncSessionPersistenceQueueName
)
621 : that
.asyncSessionPersistenceQueueName
!= null) {
624 if (envVariables
!= null ?
!envVariables
.equals(that
.envVariables
)
625 : that
.envVariables
!= null) {
628 if (errorHandlers
!= null ?
!errorHandlers
.equals(that
.errorHandlers
)
629 : that
.errorHandlers
!= null) {
632 if (inboundServices
!= null ?
!inboundServices
.equals(that
.inboundServices
)
633 : that
.inboundServices
!= null) {
636 if (majorVersionId
!= null ?
!majorVersionId
.equals(that
.majorVersionId
)
637 : that
.majorVersionId
!= null) {
640 if (sourceLanguage
!= null ?
!sourceLanguage
.equals(that
.sourceLanguage
)
641 : that
.sourceLanguage
!= null) {
644 if (publicRoot
!= null ?
!publicRoot
.equals(that
.publicRoot
) : that
.publicRoot
!= null) {
647 if (resourceExcludePattern
!= null ?
!resourceExcludePattern
.equals(that
.resourceExcludePattern
)
648 : that
.resourceExcludePattern
!= null) {
651 if (resourceFileExcludes
!= null ?
!resourceFileExcludes
.equals(that
.resourceFileExcludes
)
652 : that
.resourceFileExcludes
!= null) {
655 if (resourceFileIncludes
!= null ?
!resourceFileIncludes
.equals(that
.resourceFileIncludes
)
656 : that
.resourceFileIncludes
!= null) {
659 if (resourceIncludePattern
!= null ?
!resourceIncludePattern
.equals(that
.resourceIncludePattern
)
660 : that
.resourceIncludePattern
!= null) {
663 if (staticExcludePattern
!= null ?
!staticExcludePattern
.equals(that
.staticExcludePattern
)
664 : that
.staticExcludePattern
!= null) {
667 if (staticFileExcludes
!= null ?
!staticFileExcludes
.equals(that
.staticFileExcludes
)
668 : that
.staticFileExcludes
!= null) {
671 if (staticFileIncludes
!= null ?
!staticFileIncludes
.equals(that
.staticFileIncludes
)
672 : that
.staticFileIncludes
!= null) {
675 if (staticIncludePattern
!= null ?
!staticIncludePattern
.equals(that
.staticIncludePattern
)
676 : that
.staticIncludePattern
!= null) {
679 if (systemProperties
!= null ?
!systemProperties
.equals(that
.systemProperties
)
680 : that
.systemProperties
!= null) {
683 if (betaSettings
!= null ?
!betaSettings
.equals(that
.betaSettings
) : that
.betaSettings
!= null) {
686 if (healthCheck
!= null ?
!healthCheck
.equals(that
.healthCheck
)
687 : that
.healthCheck
!= null) {
690 if (resources
!= null ?
!resources
.equals(that
.resources
) : that
.resources
!= null) {
693 if (network
!= null ?
!network
.equals(that
.network
) : that
.network
!= null) {
696 if (userPermissions
!= null ?
!userPermissions
.equals(that
.userPermissions
)
697 : that
.userPermissions
!= null) {
700 if (apiConfig
!= null ?
!apiConfig
.equals(that
.apiConfig
)
701 : that
.apiConfig
!= null) {
704 if (apiEndpointIds
!= null ?
!apiEndpointIds
.equals(that
.apiEndpointIds
)
705 : that
.apiEndpointIds
!= null) {
708 if (pagespeed
!= null ?
!pagespeed
.equals(that
.pagespeed
) : that
.pagespeed
!= null) {
711 if (classLoaderConfig
!= null ?
!classLoaderConfig
.equals(that
.classLoaderConfig
) :
712 that
.classLoaderConfig
!= null) {
715 if (urlStreamHandlerType
!= null ?
!urlStreamHandlerType
.equals(that
.urlStreamHandlerType
) :
716 that
.urlStreamHandlerType
!= null) {
719 if (useGoogleConnectorJ
!= that
.useGoogleConnectorJ
) {
727 public int hashCode() {
728 int result
= systemProperties
!= null ? systemProperties
.hashCode() : 0;
729 result
= 31 * result
+ (envVariables
!= null ? envVariables
.hashCode() : 0);
730 result
= 31 * result
+ (userPermissions
!= null ? userPermissions
.hashCode() : 0);
731 result
= 31 * result
+ (appId
!= null ? appId
.hashCode() : 0);
732 result
= 31 * result
+ (majorVersionId
!= null ? majorVersionId
.hashCode() : 0);
733 result
= 31 * result
+ (sourceLanguage
!= null ? sourceLanguage
.hashCode() : 0);
734 result
= 31 * result
+ (module
!= null ? module
.hashCode() : 0);
735 result
= 31 * result
+ (instanceClass
!= null ? instanceClass
.hashCode() : 0);
736 result
= 31 * result
+ automaticScaling
.hashCode();
737 result
= 31 * result
+ manualScaling
.hashCode();
738 result
= 31 * result
+ basicScaling
.hashCode();
739 result
= 31 * result
+ (sslEnabled ?
1 : 0);
740 result
= 31 * result
+ (useSessions ?
1 : 0);
741 result
= 31 * result
+ (asyncSessionPersistence ?
1 : 0);
743 31 * result
+ (asyncSessionPersistenceQueueName
!= null ? asyncSessionPersistenceQueueName
745 result
= 31 * result
+ (staticFileIncludes
!= null ? staticFileIncludes
.hashCode() : 0);
746 result
= 31 * result
+ (staticFileExcludes
!= null ? staticFileExcludes
.hashCode() : 0);
747 result
= 31 * result
+ (resourceFileIncludes
!= null ? resourceFileIncludes
.hashCode() : 0);
748 result
= 31 * result
+ (resourceFileExcludes
!= null ? resourceFileExcludes
.hashCode() : 0);
749 result
= 31 * result
+ (staticIncludePattern
!= null ? staticIncludePattern
.hashCode() : 0);
750 result
= 31 * result
+ (staticExcludePattern
!= null ? staticExcludePattern
.hashCode() : 0);
751 result
= 31 * result
+ (resourceIncludePattern
!= null ? resourceIncludePattern
.hashCode() : 0);
752 result
= 31 * result
+ (resourceExcludePattern
!= null ? resourceExcludePattern
.hashCode() : 0);
753 result
= 31 * result
+ (publicRoot
!= null ? publicRoot
.hashCode() : 0);
754 result
= 31 * result
+ (appRoot
!= null ? appRoot
.hashCode() : 0);
755 result
= 31 * result
+ (inboundServices
!= null ? inboundServices
.hashCode() : 0);
756 result
= 31 * result
+ (precompilationEnabled ?
1 : 0);
757 result
= 31 * result
+ (adminConsolePages
!= null ? adminConsolePages
.hashCode() : 0);
758 result
= 31 * result
+ (errorHandlers
!= null ? errorHandlers
.hashCode() : 0);
759 result
= 31 * result
+ (threadsafe ?
1 : 0);
760 result
= 31 * result
+ (autoIdPolicy
!= null ? autoIdPolicy
.hashCode() : 0);
761 result
= 31 * result
+ (threadsafeValueProvided ?
1 : 0);
762 result
= 31 * result
+ (codeLock ?
1 : 0);
763 result
= 31 * result
+ (apiConfig
!= null ? apiConfig
.hashCode() : 0);
764 result
= 31 * result
+ (apiEndpointIds
!= null ? apiEndpointIds
.hashCode() : 0);
765 result
= 31 * result
+ (pagespeed
!= null ? pagespeed
.hashCode() : 0);
766 result
= 31 * result
+ (classLoaderConfig
!= null ? classLoaderConfig
.hashCode() : 0);
767 result
= 31 * result
+ (urlStreamHandlerType
!= null ? urlStreamHandlerType
.hashCode() : 0);
768 result
= 31 * result
+ (useGoogleConnectorJ
.hashCode());
769 result
= 31 * result
+ (betaSettings
!= null ? betaSettings
.hashCode() : 0);
770 result
= 31 * result
+ (healthCheck
!= null ? healthCheck
.hashCode() : 0);
771 result
= 31 * result
+ (resources
!= null ? resources
.hashCode() : 0);
772 result
= 31 * result
+ (network
!= null ? network
.hashCode() : 0);
776 public boolean includesResource(String path
) {
777 if (resourceIncludePattern
== null) {
778 if (resourceFileIncludes
.size() == 0) {
779 resourceIncludePattern
= Pattern
.compile(".*");
781 resourceIncludePattern
= Pattern
.compile(makeRegexp(resourceFileIncludes
));
784 if (resourceExcludePattern
== null && resourceFileExcludes
.size() > 0) {
785 resourceExcludePattern
= Pattern
.compile(makeRegexp(resourceFileExcludes
));
788 return includes(path
, resourceIncludePattern
, resourceExcludePattern
);
791 public boolean includesStatic(String path
) {
792 if (staticIncludePattern
== null) {
793 if (staticFileIncludes
.size() == 0) {
795 if (publicRoot
.length() > 0) {
796 staticRoot
= publicRoot
+ "/**";
800 staticIncludePattern
= Pattern
.compile(
801 makeRegexp(Collections
.singletonList(staticRoot
)));
803 List
<String
> patterns
= new ArrayList
<String
>();
804 for (StaticFileInclude include
: staticFileIncludes
) {
805 patterns
.add(include
.getPattern());
807 staticIncludePattern
= Pattern
.compile(makeRegexp(patterns
));
810 if (staticExcludePattern
== null && staticFileExcludes
.size() > 0) {
811 staticExcludePattern
= Pattern
.compile(makeRegexp(staticFileExcludes
));
814 return includes(path
, staticIncludePattern
, staticExcludePattern
);
818 * Tests whether {@code path} is covered by the pattern {@code includes}
819 * while not being blocked by matching {@code excludes}.
821 * @param path a URL to test
822 * @param includes a non-{@code null} pattern for included URLs
823 * @param excludes a pattern for exclusion, or {@code null} to not exclude
824 * anything from the {@code includes} set.
826 public boolean includes(String path
, Pattern includes
, Pattern excludes
) {
827 assert(includes
!= null);
828 if (!includes
.matcher(path
).matches()) {
831 if (excludes
!= null && excludes
.matcher(path
).matches()) {
837 public String
makeRegexp(List
<String
> patterns
) {
838 StringBuilder builder
= new StringBuilder();
839 boolean first
= true;
840 for (String item
: patterns
) {
847 while (item
.charAt(0) == '/') {
848 item
= item
.substring(1);
852 if (appRoot
!= null) {
853 builder
.append(makeFileRegex(appRoot
));
856 builder
.append(makeFileRegex(item
));
859 return builder
.toString();
863 * Helper method to translate from appengine-web.xml "file globs" to
864 * proper regular expressions as used in app.yaml.
866 * @param fileGlob the glob to translate
867 * @return the regular expression string matching the input {@code file} pattern.
869 static String
makeFileRegex(String fileGlob
) {
870 fileGlob
= fileGlob
.replaceAll("([^A-Za-z0-9\\-_/])", "\\\\$1");
871 fileGlob
= fileGlob
.replaceAll("\\\\\\*\\\\\\*", ".*");
872 fileGlob
= fileGlob
.replaceAll("\\\\\\*", "[^/]*");
876 * Sets the application root directory, as a prefix for the regexps in
877 * {@link #includeResourcePattern(String)} and friends. This is needed
878 * because we want to match complete filenames relative to root.
882 public void setSourcePrefix(String appRoot
) {
883 this.appRoot
= appRoot
;
884 this.resourceIncludePattern
= null;
885 this.resourceExcludePattern
= null;
886 this.staticIncludePattern
= null;
887 this.staticExcludePattern
= null;
890 public String
getSourcePrefix() {
895 * Represents a {@link java.security.Permission} that needs to be
896 * granted to user code.
898 private static class UserPermission
{
899 private final String className
;
900 private final String name
;
901 private final String actions
;
903 private boolean hasHashCode
= false;
904 private int hashCode
;
906 public UserPermission(String className
, String name
, String actions
) {
907 this.className
= className
;
909 this.actions
= actions
;
912 public String
getClassName() {
916 public String
getName() {
920 public String
getActions() {
925 public int hashCode() {
930 int hash
= className
.hashCode();
931 hash
= 31 * hash
+ name
.hashCode();
932 if (actions
!= null) {
933 hash
= 31 * hash
+ actions
.hashCode();
942 public boolean equals(Object obj
) {
943 if (obj
instanceof UserPermission
) {
944 UserPermission perm
= (UserPermission
) obj
;
945 if (className
.equals(perm
.className
) && name
.equals(perm
.name
)) {
946 if (actions
== null ? perm
.actions
== null : actions
.equals(perm
.actions
)) {
956 * Represents an <include> element within the
957 * <static-files> element. Currently this includes both a
958 * pattern and an optional expiration time specification.
960 public static class StaticFileInclude
{
961 private final String pattern
;
962 private final String expiration
;
963 private final Map
<String
, String
> httpHeaders
;
965 public StaticFileInclude(String pattern
, String expiration
) {
966 this.pattern
= pattern
;
967 this.expiration
= expiration
;
968 this.httpHeaders
= new LinkedHashMap
<>();
971 public String
getPattern() {
975 public Pattern
getRegularExpression() {
976 return Pattern
.compile(makeFileRegex(pattern
));
979 public String
getExpiration() {
983 public Map
<String
, String
> getHttpHeaders() {
988 public int hashCode() {
989 return Objects
.hash(pattern
, expiration
, httpHeaders
);
993 public boolean equals(Object obj
) {
994 if (!(obj
instanceof StaticFileInclude
)) {
998 StaticFileInclude other
= (StaticFileInclude
) obj
;
1000 if (pattern
!= null) {
1001 if (!pattern
.equals(other
.pattern
)) {
1005 if (other
.pattern
!= null) {
1010 if (expiration
!= null) {
1011 if (!expiration
.equals(other
.expiration
)) {
1015 if (other
.expiration
!= null) {
1020 if (httpHeaders
!= null) {
1021 if (!httpHeaders
.equals(other
.httpHeaders
)) {
1025 if (other
.httpHeaders
!= null) {
1034 public static class AdminConsolePage
{
1035 private final String name
;
1036 private final String url
;
1038 public AdminConsolePage(String name
, String url
) {
1043 public String
getName() {
1047 public String
getUrl() {
1052 public int hashCode() {
1053 final int prime
= 31;
1055 result
= prime
* result
+ ((name
== null) ?
0 : name
.hashCode());
1056 result
= prime
* result
+ ((url
== null) ?
0 : url
.hashCode());
1061 public boolean equals(Object obj
) {
1062 if (this == obj
) return true;
1063 if (obj
== null) return false;
1064 if (getClass() != obj
.getClass()) return false;
1065 AdminConsolePage other
= (AdminConsolePage
) obj
;
1067 if (other
.name
!= null) return false;
1068 } else if (!name
.equals(other
.name
)) return false;
1070 if (other
.url
!= null) return false;
1071 } else if (!url
.equals(other
.url
)) return false;
1077 * Represents an <error-handler> element. Currently this includes both
1078 * a file name and an optional error code.
1080 public static class ErrorHandler
{
1081 private final String file
;
1082 private final String errorCode
;
1084 public ErrorHandler(String file
, String errorCode
) {
1086 this.errorCode
= errorCode
;
1089 public String
getFile() {
1093 public String
getErrorCode() {
1098 public int hashCode() {
1099 final int prime
= 31;
1101 result
= prime
* result
+ ((file
== null) ?
0 : file
.hashCode());
1102 result
= prime
* result
+
1103 ((errorCode
== null) ?
0 : errorCode
.hashCode());
1108 public boolean equals(Object obj
) {
1109 if (!(obj
instanceof ErrorHandler
)) {
1113 ErrorHandler handler
= (ErrorHandler
) obj
;
1114 if (!file
.equals(handler
.file
)) {
1118 if (errorCode
== null) {
1119 if (handler
.errorCode
!= null) {
1123 if (!errorCode
.equals(handler
.errorCode
)) {
1133 * Represents an <api-config> element. This is a singleton specifying
1134 * url-pattern and servlet-class for the api config server.
1136 public static class ApiConfig
{
1137 private final String servletClass
;
1138 private final String url
;
1140 public ApiConfig(String servletClass
, String url
) {
1141 this.servletClass
= servletClass
;
1145 public String
getservletClass() {
1146 return servletClass
;
1149 public String
getUrl() {
1154 public int hashCode() {
1155 final int prime
= 31;
1157 result
= prime
* result
+ ((servletClass
== null) ?
0 : servletClass
.hashCode());
1158 result
= prime
* result
+ ((url
== null) ?
0 : url
.hashCode());
1163 public boolean equals(Object obj
) {
1164 if (this == obj
) { return true; }
1165 if (obj
== null) { return false; }
1166 if (getClass() != obj
.getClass()) { return false; }
1167 ApiConfig other
= (ApiConfig
) obj
;
1168 if (servletClass
== null) {
1169 if (other
.servletClass
!= null) { return false; }
1170 } else if (!servletClass
.equals(other
.servletClass
)) { return false; }
1172 if (other
.url
!= null) { return false; }
1173 } else if (!url
.equals(other
.url
)) { return false; }
1178 public String
toString() {
1179 return "ApiConfig{servletClass=\"" + servletClass
+ "\", url=\"" + url
+ "\"}";
1184 * Holder for automatic settings.
1186 public static class AutomaticScaling
{
1187 private static final AutomaticScaling EMPTY_SETTINGS
= new AutomaticScaling();
1189 public static final String AUTOMATIC
= "automatic";
1190 private String minPendingLatency
;
1191 private String maxPendingLatency
;
1192 private String minIdleInstances
;
1193 private String maxIdleInstances
;
1194 private String maxConcurrentRequests
;
1196 private Integer minNumInstances
;
1197 private Integer maxNumInstances
;
1198 private Integer coolDownPeriodSec
;
1199 private CpuUtilization cpuUtilization
;
1201 public String
getMinPendingLatency() {
1202 return minPendingLatency
;
1206 * Sets minPendingLatency. Normalizes empty and null inputs to null.
1208 public void setMinPendingLatency(String minPendingLatency
) {
1209 this.minPendingLatency
= StringUtil
.toNullIfEmptyOrWhitespace(minPendingLatency
);
1212 public String
getMaxPendingLatency() {
1213 return maxPendingLatency
;
1217 * Sets maxPendingLatency. Normalizes empty and null inputs to null.
1219 public void setMaxPendingLatency(String maxPendingLatency
) {
1220 this.maxPendingLatency
= StringUtil
.toNullIfEmptyOrWhitespace(maxPendingLatency
);
1223 public String
getMinIdleInstances() {
1224 return minIdleInstances
;
1228 * Sets minIdleInstances. Normalizes empty and null inputs to null.
1230 public void setMinIdleInstances(String minIdleInstances
) {
1231 this.minIdleInstances
= StringUtil
.toNullIfEmptyOrWhitespace(minIdleInstances
);
1234 public String
getMaxIdleInstances() {
1235 return maxIdleInstances
;
1239 * Sets maxIdleInstances. Normalizes empty and null inputs to null.
1241 public void setMaxIdleInstances(String maxIdleInstances
) {
1242 this.maxIdleInstances
= StringUtil
.toNullIfEmptyOrWhitespace(maxIdleInstances
);
1245 public boolean isEmpty() {
1246 return this.equals(EMPTY_SETTINGS
);
1249 public String
getMaxConcurrentRequests() {
1250 return maxConcurrentRequests
;
1254 * Sets maxConcurrentRequests. Normalizes empty and null inputs to null.
1256 public void setMaxConcurrentRequests(String maxConcurrentRequests
) {
1257 this.maxConcurrentRequests
= StringUtil
.toNullIfEmptyOrWhitespace(maxConcurrentRequests
);
1260 public Integer
getMinNumInstances() {
1261 return minNumInstances
;
1264 public void setMinNumInstances(Integer minNumInstances
) {
1265 this.minNumInstances
= minNumInstances
;
1268 public Integer
getMaxNumInstances() {
1269 return maxNumInstances
;
1272 public void setMaxNumInstances(Integer maxNumInstances
) {
1273 this.maxNumInstances
= maxNumInstances
;
1276 public Integer
getCoolDownPeriodSec() {
1277 return coolDownPeriodSec
;
1280 public void setCoolDownPeriodSec(Integer coolDownPeriodSec
) {
1281 this.coolDownPeriodSec
= coolDownPeriodSec
;
1284 public CpuUtilization
getCpuUtilization() {
1285 return cpuUtilization
;
1288 public void setCpuUtilization(CpuUtilization cpuUtilization
) {
1289 this.cpuUtilization
= cpuUtilization
;
1293 public int hashCode() {
1294 return Objects
.hash(maxPendingLatency
, minPendingLatency
, maxIdleInstances
,
1295 minIdleInstances
, maxConcurrentRequests
, minNumInstances
,
1296 maxNumInstances
, coolDownPeriodSec
, cpuUtilization
);
1300 public boolean equals(Object obj
) {
1307 if (getClass() != obj
.getClass()) {
1310 AutomaticScaling other
= (AutomaticScaling
) obj
;
1311 return Objects
.equals(maxPendingLatency
, other
.maxPendingLatency
)
1312 && Objects
.equals(minPendingLatency
, other
.minPendingLatency
)
1313 && Objects
.equals(maxIdleInstances
, other
.maxIdleInstances
)
1314 && Objects
.equals(minIdleInstances
, other
.minIdleInstances
)
1315 && Objects
.equals(maxConcurrentRequests
, other
.maxConcurrentRequests
)
1316 && Objects
.equals(minNumInstances
, other
.minNumInstances
)
1317 && Objects
.equals(maxNumInstances
, other
.maxNumInstances
)
1318 && Objects
.equals(coolDownPeriodSec
, other
.coolDownPeriodSec
)
1319 && Objects
.equals(cpuUtilization
, other
.cpuUtilization
);
1323 public String
toString() {
1324 return "AutomaticScaling [minPendingLatency=" + minPendingLatency
1325 + ", maxPendingLatency=" + maxPendingLatency
1326 + ", minIdleInstances=" + minIdleInstances
1327 + ", maxIdleInstances=" + maxIdleInstances
1328 + ", maxConcurrentRequests=" + maxConcurrentRequests
1329 + ", minNumInstances=" + minNumInstances
1330 + ", maxNumInstances=" + maxNumInstances
1331 + ", coolDownPeriodSec=" + coolDownPeriodSec
1332 + ", cpuUtilization=" + cpuUtilization
+ "]";
1337 * Holder for CPU utilization.
1339 public static class CpuUtilization
{
1340 private static final CpuUtilization EMPTY_SETTINGS
= new CpuUtilization();
1341 private Double targetUtilization
;
1342 private Integer aggregationWindowLengthSec
;
1344 public Double
getTargetUtilization() {
1345 return targetUtilization
;
1348 public void setTargetUtilization(Double targetUtilization
) {
1349 this.targetUtilization
= targetUtilization
;
1352 public Integer
getAggregationWindowLengthSec() {
1353 return aggregationWindowLengthSec
;
1356 public void setAggregationWindowLengthSec(Integer aggregationWindowLengthSec
) {
1357 this.aggregationWindowLengthSec
= aggregationWindowLengthSec
;
1360 public boolean isEmpty() {
1361 return this.equals(EMPTY_SETTINGS
);
1365 public int hashCode() {
1366 return Objects
.hash(targetUtilization
, aggregationWindowLengthSec
);
1370 public boolean equals(Object obj
) {
1377 if (getClass() != obj
.getClass()) {
1380 CpuUtilization other
= (CpuUtilization
) obj
;
1381 return Objects
.equals(targetUtilization
, other
.targetUtilization
)
1382 && Objects
.equals(aggregationWindowLengthSec
, other
.aggregationWindowLengthSec
);
1386 public String
toString() {
1387 return "CpuUtilization [targetUtilization=" + targetUtilization
1388 + ", aggregationWindowLengthSec=" + aggregationWindowLengthSec
+ "]";
1393 * Holder for health check.
1395 public static class HealthCheck
{
1396 private static final HealthCheck EMPTY_SETTINGS
= new HealthCheck();
1398 private boolean enableHealthCheck
= true;
1399 private Integer checkIntervalSec
;
1400 private Integer timeoutSec
;
1401 private Integer unhealthyThreshold
;
1402 private Integer healthyThreshold
;
1403 private Integer restartThreshold
;
1404 private String host
;
1406 public boolean getEnableHealthCheck() {
1407 return enableHealthCheck
;
1410 * Sets enableHealthCheck.
1412 public void setEnableHealthCheck(boolean enableHealthCheck
) {
1413 this.enableHealthCheck
= enableHealthCheck
;
1416 public Integer
getCheckIntervalSec() {
1417 return checkIntervalSec
;
1420 * Sets checkIntervalSec.
1422 public void setCheckIntervalSec(Integer checkIntervalSec
) {
1423 this.checkIntervalSec
= checkIntervalSec
;
1426 public Integer
getTimeoutSec() {
1432 public void setTimeoutSec(Integer timeoutSec
) {
1433 this.timeoutSec
= timeoutSec
;
1436 public Integer
getUnhealthyThreshold() {
1437 return unhealthyThreshold
;
1441 * Sets unhealthyThreshold.
1443 public void setUnhealthyThreshold(Integer unhealthyThreshold
) {
1444 this.unhealthyThreshold
= unhealthyThreshold
;
1447 public Integer
getHealthyThreshold() {
1448 return healthyThreshold
;
1452 * Sets healthyThreshold.
1455 public void setHealthyThreshold(Integer healthyThreshold
) {
1456 this.healthyThreshold
= healthyThreshold
;
1459 public Integer
getRestartThreshold() {
1460 return restartThreshold
;
1464 * Sets restartThreshold.
1466 public void setRestartThreshold(Integer restartThreshold
) {
1467 this.restartThreshold
= restartThreshold
;
1470 public String
getHost() {
1475 * Sets host. Normalizes empty and null inputs to null.
1477 public void setHost(String host
) {
1478 this.host
= StringUtil
.toNullIfEmptyOrWhitespace(host
);
1481 public boolean isEmpty() {
1482 return this.equals(EMPTY_SETTINGS
);
1486 public int hashCode() {
1487 return Objects
.hash(enableHealthCheck
, checkIntervalSec
, timeoutSec
, unhealthyThreshold
,
1488 healthyThreshold
, restartThreshold
, host
);
1492 public boolean equals(Object obj
) {
1499 if (getClass() != obj
.getClass()) {
1502 HealthCheck other
= (HealthCheck
) obj
;
1503 return Objects
.equals(enableHealthCheck
, other
.enableHealthCheck
)
1504 && Objects
.equals(checkIntervalSec
, other
.checkIntervalSec
)
1505 && Objects
.equals(timeoutSec
, other
.timeoutSec
)
1506 && Objects
.equals(unhealthyThreshold
, other
.unhealthyThreshold
)
1507 && Objects
.equals(healthyThreshold
, other
.healthyThreshold
)
1508 && Objects
.equals(restartThreshold
, other
.restartThreshold
)
1509 && Objects
.equals(host
, other
.host
);
1513 public String
toString() {
1514 return "HealthCheck [enableHealthCheck=" + enableHealthCheck
1515 + ", checkIntervalSec=" + checkIntervalSec
1516 + ", timeoutSec=" + timeoutSec
1517 + ", unhealthyThreshold=" + unhealthyThreshold
1518 + ", healthyThreshold=" + healthyThreshold
1519 + ", restartThreshold=" + restartThreshold
1520 + ", host=" + host
+ "]";
1525 * Holder for Resources
1527 public static class Resources
{
1528 private static final Resources EMPTY_SETTINGS
= new Resources();
1532 public double getCpu() {
1536 public void setCpu(double cpu
) {
1540 private double memory_gb
;
1542 public double getMemoryGb() {
1546 public void setMemoryGb(double memory_gb
) {
1547 this.memory_gb
= memory_gb
;
1550 private int disk_size_gb
;
1552 public int getDiskSizeGb() {
1553 return disk_size_gb
;
1556 public void setDiskSizeGb(int disk_size_gb
) {
1557 this.disk_size_gb
= disk_size_gb
;
1560 public boolean isEmpty() {
1561 return this.equals(EMPTY_SETTINGS
);
1565 public int hashCode() {
1566 return Objects
.hash(cpu
, memory_gb
, disk_size_gb
);
1570 public boolean equals(Object obj
) {
1577 if (getClass() != obj
.getClass()) {
1580 Resources other
= (Resources
) obj
;
1581 return Objects
.equals(cpu
, other
.cpu
) &&
1582 Objects
.equals(memory_gb
, other
.memory_gb
) &&
1583 Objects
.equals(disk_size_gb
, other
.disk_size_gb
);
1587 public String
toString() {
1588 return "Resources [" + "cpu=" + cpu
+
1589 ", memory_gb=" + memory_gb
+
1590 ", disk_size_gb=" + disk_size_gb
+ "]";
1595 * Holder for network.
1597 public static class Network
{
1598 private static final Network EMPTY_SETTINGS
= new Network();
1600 private String instanceTag
;
1602 public String
getInstanceTag() {
1606 public void setInstanceTag(String instanceTag
) {
1607 this.instanceTag
= instanceTag
;
1610 private final List
<String
> forwardedPorts
= Lists
.newArrayList();
1612 public List
<String
> getForwardedPorts() {
1613 return Collections
.unmodifiableList(forwardedPorts
);
1616 public void addForwardedPort(String forwardedPort
) {
1617 forwardedPorts
.add(forwardedPort
);
1620 public boolean isEmpty() {
1621 return this.equals(EMPTY_SETTINGS
);
1625 public int hashCode() {
1626 return Objects
.hash(forwardedPorts
, instanceTag
);
1630 public boolean equals(Object obj
) {
1637 if (getClass() != obj
.getClass()) {
1640 Network other
= (Network
) obj
;
1641 return Objects
.equals(forwardedPorts
, other
.forwardedPorts
)
1642 && Objects
.equals(instanceTag
, other
.instanceTag
);
1646 public String
toString() {
1647 return "Network [forwardedPorts=" + forwardedPorts
+ ", instanceTag=" + instanceTag
+ "]";
1652 * Holder for manual settings.
1654 public static class ManualScaling
{
1655 private static final ManualScaling EMPTY_SETTINGS
= new ManualScaling();
1657 private String instances
;
1659 public String
getInstances() {
1664 * Sets instances. Normalizes empty and null inputs to null.
1666 public void setInstances(String instances
) {
1667 this.instances
= StringUtil
.toNullIfEmptyOrWhitespace(instances
);
1670 public boolean isEmpty() {
1671 return this.equals(EMPTY_SETTINGS
);
1675 public int hashCode() {
1676 return Objects
.hash(instances
);
1680 public boolean equals(Object obj
) {
1687 if (getClass() != obj
.getClass()) {
1690 ManualScaling other
= (ManualScaling
) obj
;
1691 return Objects
.equals(instances
, other
.instances
);
1695 public String
toString() {
1696 return "ManualScaling [" + "instances=" + instances
+ "]";
1701 * Holder for basic settings.
1703 public static class BasicScaling
{
1704 private static final BasicScaling EMPTY_SETTINGS
= new BasicScaling();
1706 private String maxInstances
;
1707 private String idleTimeout
;
1709 public String
getMaxInstances() {
1710 return maxInstances
;
1713 public String
getIdleTimeout() {
1718 * Sets maxInstances. Normalizes empty and null inputs to null.
1720 public void setMaxInstances(String maxInstances
) {
1721 this.maxInstances
= StringUtil
.toNullIfEmptyOrWhitespace(maxInstances
);
1725 * Sets idleTimeout. Normalizes empty and null inputs to null.
1727 public void setIdleTimeout(String idleTimeout
) {
1728 this.idleTimeout
= StringUtil
.toNullIfEmptyOrWhitespace(idleTimeout
);
1731 public boolean isEmpty() {
1732 return this.equals(EMPTY_SETTINGS
);
1736 public int hashCode() {
1737 return Objects
.hash(maxInstances
, idleTimeout
);
1741 public boolean equals(Object obj
) {
1748 if (getClass() != obj
.getClass()) {
1751 BasicScaling other
= (BasicScaling
) obj
;
1752 return Objects
.equals(maxInstances
, other
.maxInstances
)
1753 && Objects
.equals(idleTimeout
, other
.idleTimeout
);
1757 public String
toString() {
1758 return "BasicScaling [" + "maxInstances=" + maxInstances
1759 + ", idleTimeout=" + idleTimeout
+ "]";
1764 * Represents a <pagespeed> element. This is used to specify configuration for the Page
1765 * Speed Service, which can be used to automatically optimize the loading speed of app engine
1768 public static class Pagespeed
{
1769 private final List
<String
> urlBlacklist
= Lists
.newArrayList();
1770 private final List
<String
> domainsToRewrite
= Lists
.newArrayList();
1771 private final List
<String
> enabledRewriters
= Lists
.newArrayList();
1772 private final List
<String
> disabledRewriters
= Lists
.newArrayList();
1774 public void addUrlBlacklist(String url
) {
1775 urlBlacklist
.add(url
);
1778 public List
<String
> getUrlBlacklist() {
1779 return Collections
.unmodifiableList(urlBlacklist
);
1782 public void addDomainToRewrite(String domain
) {
1783 domainsToRewrite
.add(domain
);
1786 public List
<String
> getDomainsToRewrite() {
1787 return Collections
.unmodifiableList(domainsToRewrite
);
1790 public void addEnabledRewriter(String rewriter
) {
1791 enabledRewriters
.add(rewriter
);
1794 public List
<String
> getEnabledRewriters() {
1795 return Collections
.unmodifiableList(enabledRewriters
);
1798 public void addDisabledRewriter(String rewriter
) {
1799 disabledRewriters
.add(rewriter
);
1802 public List
<String
> getDisabledRewriters() {
1803 return Collections
.unmodifiableList(disabledRewriters
);
1806 public boolean isEmpty() {
1807 return urlBlacklist
.isEmpty() && domainsToRewrite
.isEmpty() && enabledRewriters
.isEmpty()
1808 && disabledRewriters
.isEmpty();
1812 public int hashCode() {
1813 return Objects
.hash(urlBlacklist
, domainsToRewrite
, enabledRewriters
, disabledRewriters
);
1817 public boolean equals(Object obj
) {
1824 if (getClass() != obj
.getClass()) {
1827 Pagespeed other
= (Pagespeed
) obj
;
1828 return Objects
.equals(urlBlacklist
, other
.urlBlacklist
)
1829 && Objects
.equals(domainsToRewrite
, other
.domainsToRewrite
)
1830 && Objects
.equals(enabledRewriters
, other
.enabledRewriters
)
1831 && Objects
.equals(disabledRewriters
, other
.disabledRewriters
);
1835 public String
toString() {
1836 return "Pagespeed [urlBlacklist=" + urlBlacklist
+ ", domainsToRewrite=" + domainsToRewrite
1837 + ", enabledRewriters=" + enabledRewriters
+ ", disabledRewriters=" + disabledRewriters
1842 public static class ClassLoaderConfig
{
1843 private final List
<PrioritySpecifierEntry
> entries
= Lists
.newArrayList();
1845 public void add(PrioritySpecifierEntry entry
) {
1849 public List
<PrioritySpecifierEntry
> getEntries() {
1854 public int hashCode() {
1855 final int prime
= 31;
1857 result
= prime
* result
+ ((entries
== null) ?
0 : entries
.hashCode());
1862 public boolean equals(Object obj
) {
1863 if (this == obj
) return true;
1864 if (obj
== null) return false;
1865 if (getClass() != obj
.getClass()) return false;
1866 ClassLoaderConfig other
= (ClassLoaderConfig
) obj
;
1867 if (entries
== null) {
1868 if (other
.entries
!= null) return false;
1869 } else if (!entries
.equals(other
.entries
)) return false;
1874 public String
toString() {
1875 return "ClassLoaderConfig{entries=\"" + entries
+ "\"}";
1879 public static class PrioritySpecifierEntry
{
1880 private String filename
;
1881 private Double priority
;
1883 private void checkNotAlreadySet() {
1884 if (filename
!= null) {
1885 throw new AppEngineConfigException("Found more that one file name matching tag. "
1886 + "Only one of 'filename' attribute allowed.");
1890 public String
getFilename() {
1894 public void setFilename(String filename
) {
1895 checkNotAlreadySet();
1896 this.filename
= filename
;
1899 public Double
getPriority() {
1903 public double getPriorityValue() {
1904 if (priority
== null) {
1910 public void setPriority(String priority
) {
1911 if (this.priority
!= null) {
1912 throw new AppEngineConfigException("The 'priority' tag may only be specified once.");
1915 if (priority
== null) {
1916 this.priority
= null;
1920 this.priority
= Double
.parseDouble(priority
);
1923 public void checkClassLoaderConfig() {
1924 if (filename
== null) {
1925 throw new AppEngineConfigException("Must have a filename attribute.");
1930 public int hashCode() {
1931 final int prime
= 31;
1933 result
= prime
* result
+ ((filename
== null) ?
0 : filename
.hashCode());
1934 result
= prime
* result
+ ((priority
== null) ?
0 : priority
.hashCode());
1939 public boolean equals(Object obj
) {
1940 if (this == obj
) return true;
1941 if (obj
== null) return false;
1942 if (getClass() != obj
.getClass()) return false;
1943 PrioritySpecifierEntry other
= (PrioritySpecifierEntry
) obj
;
1944 if (filename
== null) {
1945 if (other
.filename
!= null) return false;
1946 } else if (!filename
.equals(other
.filename
)) return false;
1947 if (priority
== null) {
1948 if (other
.priority
!= null) return false;
1949 } else if (!priority
.equals(other
.priority
)) return false;
1954 public String
toString() {
1955 return "PrioritySpecifierEntry{filename=\"" + filename
+ "\", priority=\"" + priority
+ "\"}";