App Engine Java SDK version 1.9.25
[gae.git] / java / src / main / com / google / apphosting / utils / config / AppEngineWebXml.java
blobc892391408b112a7744d6a3ffe23f02979e9469d
1 // Copyright 2008 Google Inc. All Rights Reserved.
2 package com.google.apphosting.utils.config;
4 import com.google.common.base.CharMatcher;
5 import com.google.common.collect.Lists;
6 import com.google.common.collect.Maps;
8 import java.security.Permissions;
9 import java.security.UnresolvedPermission;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.LinkedHashMap;
13 import java.util.LinkedHashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Objects;
17 import java.util.Set;
18 import java.util.regex.Pattern;
20 /**
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 {
28 /**
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";
52 private String appId;
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 String env = "1";
101 private ApiConfig apiConfig;
102 private final List<String> apiEndpointIds;
103 private Pagespeed pagespeed;
106 * Represent user's choice w.r.t the usage of Google's customized connector-j.
108 public static enum UseGoogleConnectorJ {
109 NOT_STATED_BY_USER,
110 TRUE,
111 FALSE,
113 private UseGoogleConnectorJ useGoogleConnectorJ = UseGoogleConnectorJ.NOT_STATED_BY_USER;
115 public AppEngineWebXml() {
116 automaticScaling = new AutomaticScaling();
117 manualScaling = new ManualScaling();
118 basicScaling = new BasicScaling();
119 healthCheck = new HealthCheck();
120 resources = new Resources();
121 network = new Network();
123 staticFileIncludes = new ArrayList<StaticFileInclude>();
124 staticFileExcludes = new ArrayList<String>();
125 staticFileExcludes.add("WEB-INF/**");
126 staticFileExcludes.add("**.jsp");
127 resourceFileIncludes = new ArrayList<String>();
128 resourceFileExcludes = new ArrayList<String>();
129 inboundServices = new LinkedHashSet<String>();
130 apiEndpointIds = new ArrayList<String>();
133 public AppEngineWebXml clone() {
134 try {
135 return (AppEngineWebXml) super.clone();
136 } catch (CloneNotSupportedException ce) {
137 throw new RuntimeException("Could not clone AppEngineWebXml", ce);
142 * @return An unmodifiable map whose entries correspond to the
143 * system properties defined in appengine-web.xml.
145 public Map<String, String> getSystemProperties() {
146 return Collections.unmodifiableMap(systemProperties);
149 public void addSystemProperty(String key, String value) {
150 systemProperties.put(key, value);
154 * @return An unmodifiable map whose entires correspond to the
155 * vm settings defined in appengine-web.xml.
157 public Map<String, String> getBetaSettings() {
158 return Collections.unmodifiableMap(betaSettings);
161 public void addBetaSetting(String key, String value) {
162 betaSettings.put(key, value);
165 public HealthCheck getHealthCheck() {
166 return healthCheck;
169 public Resources getResources() {
170 return resources;
173 public Network getNetwork() {
174 return network;
178 * @return An unmodifiable map whose entires correspond to the
179 * environment variables defined in appengine-web.xml.
181 public Map<String, String> getEnvironmentVariables() {
182 return Collections.unmodifiableMap(envVariables);
185 public void addEnvironmentVariable(String key, String value) {
186 envVariables.put(key, value);
189 public String getAppId() {
190 return appId;
193 public void setAppId(String appId) {
194 this.appId = appId;
197 public String getMajorVersionId() {
198 return majorVersionId;
201 public void setMajorVersionId(String majorVersionId) {
202 this.majorVersionId = majorVersionId;
205 public String getSourceLanguage() {
206 return this.sourceLanguage;
209 public void setSourceLanguage(String sourceLanguage) {
210 this.sourceLanguage = sourceLanguage;
213 public String getModule() {
214 return module;
218 * Sets instanceClass (aka class in the xml/yaml files). Normalizes empty and null
219 * inputs to null.
221 public void setInstanceClass(String instanceClass) {
222 this.instanceClass = toNullIfEmptyOrWhitespace(instanceClass);
225 public String getInstanceClass() {
226 return instanceClass;
229 public AutomaticScaling getAutomaticScaling() {
230 return automaticScaling;
233 public ManualScaling getManualScaling() {
234 return manualScaling;
237 public BasicScaling getBasicScaling() {
238 return basicScaling;
241 public ScalingType getScalingType() {
242 if (!getBasicScaling().isEmpty()) {
243 return ScalingType.BASIC;
244 } else if (!getManualScaling().isEmpty()) {
245 return ScalingType.MANUAL;
246 } else {
247 return ScalingType.AUTOMATIC;
251 public void setModule(String module) {
252 this.module = module;
255 public void setSslEnabled(boolean ssl) {
256 sslEnabled = ssl;
259 public boolean getSslEnabled() {
260 return sslEnabled;
263 public void setSessionsEnabled(boolean sessions) {
264 useSessions = sessions;
267 public boolean getSessionsEnabled() {
268 return useSessions;
271 public void setAsyncSessionPersistence(boolean asyncSessionPersistence) {
272 this.asyncSessionPersistence = asyncSessionPersistence;
275 public boolean getAsyncSessionPersistence() {
276 return asyncSessionPersistence;
279 public void setAsyncSessionPersistenceQueueName(String asyncSessionPersistenceQueueName) {
280 this.asyncSessionPersistenceQueueName = asyncSessionPersistenceQueueName;
283 public String getAsyncSessionPersistenceQueueName() {
284 return asyncSessionPersistenceQueueName;
287 public List<StaticFileInclude> getStaticFileIncludes() {
288 return staticFileIncludes;
291 public List<String> getStaticFileExcludes() {
292 return staticFileExcludes;
295 public StaticFileInclude includeStaticPattern(String pattern, String expiration) {
296 staticIncludePattern = null;
297 StaticFileInclude staticFileInclude = new StaticFileInclude(pattern, expiration);
298 staticFileIncludes.add(staticFileInclude);
299 return staticFileInclude;
302 public void excludeStaticPattern(String url) {
303 staticExcludePattern = null;
304 staticFileExcludes.add(url);
307 public List<String> getResourcePatterns() {
308 return resourceFileIncludes;
311 public List<String> getResourceFileExcludes() {
312 return resourceFileExcludes;
315 public void includeResourcePattern(String url) {
316 resourceExcludePattern = null;
317 resourceFileIncludes.add(url);
320 public void excludeResourcePattern(String url) {
321 resourceIncludePattern = null;
322 resourceFileExcludes.add(url);
325 public void addUserPermission(String className, String name, String actions) {
326 if (className.startsWith("java.")) {
327 throw new AppEngineConfigException("Cannot specify user-permissions for " +
328 "classes in java.* packages.");
331 userPermissions.add(new UserPermission(className, name, actions));
334 public Permissions getUserPermissions() {
335 Permissions permissions = new Permissions();
336 for (UserPermission permission : userPermissions) {
337 permissions.add(new UnresolvedPermission(permission.getClassName(),
338 permission.getName(),
339 permission.getActions(),
340 null));
342 permissions.setReadOnly();
343 return permissions;
346 public void setPublicRoot(String root) {
347 if (root.indexOf('*') != -1) {
348 throw new AppEngineConfigException("public-root cannot contain wildcards");
350 if (root.endsWith("/")) {
351 root = root.substring(0, root.length() - 1);
353 if (root.length() > 0 && !root.startsWith("/")) {
354 root = "/" + root;
356 staticIncludePattern = null;
357 publicRoot = root;
360 public String getPublicRoot() {
361 return publicRoot;
364 public void addInboundService(String service) {
365 inboundServices.add(service);
368 public Set<String> getInboundServices() {
369 return inboundServices;
372 public boolean getPrecompilationEnabled() {
373 return precompilationEnabled;
376 public void setPrecompilationEnabled(boolean precompilationEnabled) {
377 this.precompilationEnabled = precompilationEnabled;
380 public boolean getWarmupRequestsEnabled() {
381 return inboundServices.contains(WARMUP_SERVICE);
384 public void setWarmupRequestsEnabled(boolean warmupRequestsEnabled) {
385 if (warmupRequestsEnabled) {
386 inboundServices.add(WARMUP_SERVICE);
387 } else {
388 inboundServices.remove(WARMUP_SERVICE);
392 public List<AdminConsolePage> getAdminConsolePages() {
393 return Collections.unmodifiableList(adminConsolePages);
396 public void addAdminConsolePage(AdminConsolePage page) {
397 adminConsolePages.add(page);
400 public List<ErrorHandler> getErrorHandlers() {
401 return Collections.unmodifiableList(errorHandlers);
404 public void addErrorHandler(ErrorHandler handler) {
405 errorHandlers.add(handler);
408 public boolean getThreadsafe() {
409 return threadsafe;
412 public boolean getThreadsafeValueProvided() {
413 return threadsafeValueProvided;
416 public void setThreadsafe(boolean threadsafe) {
417 this.threadsafe = threadsafe;
418 this.threadsafeValueProvided = true;
421 public void setAutoIdPolicy(String policy) {
422 autoIdPolicy = policy;
425 public String getAutoIdPolicy() {
426 return autoIdPolicy;
429 public boolean getCodeLock() {
430 return codeLock;
433 public void setCodeLock(boolean codeLock) {
434 this.codeLock = codeLock;
437 public void setUseVm(boolean useVm) {
438 this.useVm = useVm;
441 public boolean getUseVm() {
442 return useVm;
445 public void setEnv(String env) {
446 this.env = env;
449 public String getEnv() {
450 return env;
453 public ApiConfig getApiConfig() {
454 return apiConfig;
457 public void setApiConfig(ApiConfig config) {
458 apiConfig = config;
461 public ClassLoaderConfig getClassLoaderConfig() {
462 return classLoaderConfig;
465 public void setClassLoaderConfig(ClassLoaderConfig classLoaderConfig) {
466 if (this.classLoaderConfig != null) {
467 throw new AppEngineConfigException("class-loader-config may only be specified once.");
469 this.classLoaderConfig = classLoaderConfig;
472 public String getUrlStreamHandlerType() {
473 return urlStreamHandlerType;
476 public void setUrlStreamHandlerType(String urlStreamHandlerType) {
477 if (this.classLoaderConfig != null) {
478 throw new AppEngineConfigException("url-stream-handler may only be specified once.");
480 if (!URL_HANDLER_URLFETCH.equals(urlStreamHandlerType)
481 && !URL_HANDLER_NATIVE.equals(urlStreamHandlerType)) {
482 throw new AppEngineConfigException(
483 "url-stream-handler must be " + URL_HANDLER_URLFETCH + " or " + URL_HANDLER_NATIVE +
484 " given " + urlStreamHandlerType);
486 this.urlStreamHandlerType = urlStreamHandlerType;
490 * Returns true if {@code url} matches one of the servlets or servlet
491 * filters listed in this web.xml that has api-endpoint set to true.
493 public boolean isApiEndpoint(String id) {
494 return apiEndpointIds.contains(id);
497 public void addApiEndpoint(String id) {
498 apiEndpointIds.add(id);
501 public Pagespeed getPagespeed() {
502 return pagespeed;
505 public void setPagespeed(Pagespeed pagespeed) {
506 this.pagespeed = pagespeed;
509 public void setUseGoogleConnectorJ(boolean useGoogleConnectorJ) {
510 if (useGoogleConnectorJ) {
511 this.useGoogleConnectorJ = UseGoogleConnectorJ.TRUE;
512 } else {
513 this.useGoogleConnectorJ = UseGoogleConnectorJ.FALSE;
517 public UseGoogleConnectorJ getUseGoogleConnectorJ() {
518 return useGoogleConnectorJ;
521 @Override
522 public String toString() {
523 return "AppEngineWebXml{" +
524 "systemProperties=" + systemProperties +
525 ", envVariables=" + envVariables +
526 ", userPermissions=" + userPermissions +
527 ", appId='" + appId + '\'' +
528 ", majorVersionId='" + majorVersionId + '\'' +
529 ", sourceLanguage='" + sourceLanguage + '\'' +
530 ", module='" + module + '\'' +
531 ", instanceClass='" + instanceClass + '\'' +
532 ", automaticScaling=" + automaticScaling +
533 ", manualScaling=" + manualScaling +
534 ", basicScaling=" + basicScaling +
535 ", healthCheck=" + healthCheck +
536 ", resources=" + resources +
537 ", network=" + network +
538 ", sslEnabled=" + sslEnabled +
539 ", useSessions=" + useSessions +
540 ", asyncSessionPersistence=" + asyncSessionPersistence +
541 ", asyncSessionPersistenceQueueName='" + asyncSessionPersistenceQueueName + '\'' +
542 ", staticFileIncludes=" + staticFileIncludes +
543 ", staticFileExcludes=" + staticFileExcludes +
544 ", resourceFileIncludes=" + resourceFileIncludes +
545 ", resourceFileExcludes=" + resourceFileExcludes +
546 ", staticIncludePattern=" + staticIncludePattern +
547 ", staticExcludePattern=" + staticExcludePattern +
548 ", resourceIncludePattern=" + resourceIncludePattern +
549 ", resourceExcludePattern=" + resourceExcludePattern +
550 ", publicRoot='" + publicRoot + '\'' +
551 ", appRoot='" + appRoot + '\'' +
552 ", inboundServices=" + inboundServices +
553 ", precompilationEnabled=" + precompilationEnabled +
554 ", adminConsolePages=" + adminConsolePages +
555 ", errorHandlers=" + errorHandlers +
556 ", threadsafe=" + threadsafe +
557 ", threadsafeValueProvided=" + threadsafeValueProvided +
558 ", autoIdPolicy=" + autoIdPolicy +
559 ", codeLock=" + codeLock +
560 ", apiConfig=" + apiConfig +
561 ", apiEndpointIds=" + apiEndpointIds +
562 ", pagespeed=" + pagespeed +
563 ", classLoaderConfig=" + classLoaderConfig +
564 ", urlStreamHandlerType=" +
565 (urlStreamHandlerType == null ? URL_HANDLER_URLFETCH : urlStreamHandlerType) +
566 ", useGoogleConnectorJ=" + useGoogleConnectorJ +
567 '}';
570 @Override
571 public boolean equals(Object o) {
572 if (this == o) {
573 return true;
575 if (o == null || getClass() != o.getClass()) {
576 return false;
579 AppEngineWebXml that = (AppEngineWebXml) o;
581 if (asyncSessionPersistence != that.asyncSessionPersistence) {
582 return false;
584 if (precompilationEnabled != that.precompilationEnabled) {
585 return false;
587 if (sslEnabled != that.sslEnabled) {
588 return false;
590 if (threadsafe != that.threadsafe) {
591 return false;
593 if (threadsafeValueProvided != that.threadsafeValueProvided) {
594 return false;
596 if (autoIdPolicy != null ? !autoIdPolicy.equals(that.autoIdPolicy)
597 : that.autoIdPolicy != null) {
598 return false;
600 if (codeLock != that.codeLock) {
601 return false;
603 if (useSessions != that.useSessions) {
604 return false;
606 if (adminConsolePages != null ? !adminConsolePages.equals(that.adminConsolePages)
607 : that.adminConsolePages != null) {
608 return false;
610 if (appId != null ? !appId.equals(that.appId) : that.appId != null) {
611 return false;
613 if (majorVersionId != null ? !majorVersionId.equals(that.majorVersionId)
614 : that.majorVersionId != null) {
615 return false;
617 if (module != null ? !module.equals(that.module) : that.module != null) {
618 return false;
620 if (instanceClass != null ? !instanceClass.equals(that.instanceClass)
621 : that.instanceClass != null) {
622 return false;
624 if (!automaticScaling.equals(that.automaticScaling)) {
625 return false;
627 if (!manualScaling.equals(that.manualScaling)) {
628 return false;
630 if (!basicScaling.equals(that.basicScaling)) {
631 return false;
633 if (appRoot != null ? !appRoot.equals(that.appRoot) : that.appRoot != null) {
634 return false;
636 if (asyncSessionPersistenceQueueName != null ? !asyncSessionPersistenceQueueName
637 .equals(that.asyncSessionPersistenceQueueName)
638 : that.asyncSessionPersistenceQueueName != null) {
639 return false;
641 if (envVariables != null ? !envVariables.equals(that.envVariables)
642 : that.envVariables != null) {
643 return false;
645 if (errorHandlers != null ? !errorHandlers.equals(that.errorHandlers)
646 : that.errorHandlers != null) {
647 return false;
649 if (inboundServices != null ? !inboundServices.equals(that.inboundServices)
650 : that.inboundServices != null) {
651 return false;
653 if (majorVersionId != null ? !majorVersionId.equals(that.majorVersionId)
654 : that.majorVersionId != null) {
655 return false;
657 if (sourceLanguage != null ? !sourceLanguage.equals(that.sourceLanguage)
658 : that.sourceLanguage != null) {
659 return false;
661 if (publicRoot != null ? !publicRoot.equals(that.publicRoot) : that.publicRoot != null) {
662 return false;
664 if (resourceExcludePattern != null ? !resourceExcludePattern.equals(that.resourceExcludePattern)
665 : that.resourceExcludePattern != null) {
666 return false;
668 if (resourceFileExcludes != null ? !resourceFileExcludes.equals(that.resourceFileExcludes)
669 : that.resourceFileExcludes != null) {
670 return false;
672 if (resourceFileIncludes != null ? !resourceFileIncludes.equals(that.resourceFileIncludes)
673 : that.resourceFileIncludes != null) {
674 return false;
676 if (resourceIncludePattern != null ? !resourceIncludePattern.equals(that.resourceIncludePattern)
677 : that.resourceIncludePattern != null) {
678 return false;
680 if (staticExcludePattern != null ? !staticExcludePattern.equals(that.staticExcludePattern)
681 : that.staticExcludePattern != null) {
682 return false;
684 if (staticFileExcludes != null ? !staticFileExcludes.equals(that.staticFileExcludes)
685 : that.staticFileExcludes != null) {
686 return false;
688 if (staticFileIncludes != null ? !staticFileIncludes.equals(that.staticFileIncludes)
689 : that.staticFileIncludes != null) {
690 return false;
692 if (staticIncludePattern != null ? !staticIncludePattern.equals(that.staticIncludePattern)
693 : that.staticIncludePattern != null) {
694 return false;
696 if (systemProperties != null ? !systemProperties.equals(that.systemProperties)
697 : that.systemProperties != null) {
698 return false;
700 if (betaSettings != null ? !betaSettings.equals(that.betaSettings) : that.betaSettings != null) {
701 return false;
703 if (healthCheck != null ? !healthCheck.equals(that.healthCheck)
704 : that.healthCheck != null) {
705 return false;
707 if (resources != null ? !resources.equals(that.resources) : that.resources != null) {
708 return false;
710 if (network != null ? !network.equals(that.network) : that.network != null) {
711 return false;
713 if (userPermissions != null ? !userPermissions.equals(that.userPermissions)
714 : that.userPermissions != null) {
715 return false;
717 if (apiConfig != null ? !apiConfig.equals(that.apiConfig)
718 : that.apiConfig != null) {
719 return false;
721 if (apiEndpointIds != null ? !apiEndpointIds.equals(that.apiEndpointIds)
722 : that.apiEndpointIds != null) {
723 return false;
725 if (pagespeed != null ? !pagespeed.equals(that.pagespeed) : that.pagespeed != null) {
726 return false;
728 if (classLoaderConfig != null ? !classLoaderConfig.equals(that.classLoaderConfig) :
729 that.classLoaderConfig != null) {
730 return false;
732 if (urlStreamHandlerType != null ? !urlStreamHandlerType.equals(that.urlStreamHandlerType) :
733 that.urlStreamHandlerType != null) {
734 return false;
736 if (useGoogleConnectorJ != that.useGoogleConnectorJ) {
737 return false;
740 return true;
743 @Override
744 public int hashCode() {
745 int result = systemProperties != null ? systemProperties.hashCode() : 0;
746 result = 31 * result + (envVariables != null ? envVariables.hashCode() : 0);
747 result = 31 * result + (userPermissions != null ? userPermissions.hashCode() : 0);
748 result = 31 * result + (appId != null ? appId.hashCode() : 0);
749 result = 31 * result + (majorVersionId != null ? majorVersionId.hashCode() : 0);
750 result = 31 * result + (sourceLanguage != null ? sourceLanguage.hashCode() : 0);
751 result = 31 * result + (module != null ? module.hashCode() : 0);
752 result = 31 * result + (instanceClass != null ? instanceClass.hashCode() : 0);
753 result = 31 * result + automaticScaling.hashCode();
754 result = 31 * result + manualScaling.hashCode();
755 result = 31 * result + basicScaling.hashCode();
756 result = 31 * result + (sslEnabled ? 1 : 0);
757 result = 31 * result + (useSessions ? 1 : 0);
758 result = 31 * result + (asyncSessionPersistence ? 1 : 0);
759 result =
760 31 * result + (asyncSessionPersistenceQueueName != null ? asyncSessionPersistenceQueueName
761 .hashCode() : 0);
762 result = 31 * result + (staticFileIncludes != null ? staticFileIncludes.hashCode() : 0);
763 result = 31 * result + (staticFileExcludes != null ? staticFileExcludes.hashCode() : 0);
764 result = 31 * result + (resourceFileIncludes != null ? resourceFileIncludes.hashCode() : 0);
765 result = 31 * result + (resourceFileExcludes != null ? resourceFileExcludes.hashCode() : 0);
766 result = 31 * result + (staticIncludePattern != null ? staticIncludePattern.hashCode() : 0);
767 result = 31 * result + (staticExcludePattern != null ? staticExcludePattern.hashCode() : 0);
768 result = 31 * result + (resourceIncludePattern != null ? resourceIncludePattern.hashCode() : 0);
769 result = 31 * result + (resourceExcludePattern != null ? resourceExcludePattern.hashCode() : 0);
770 result = 31 * result + (publicRoot != null ? publicRoot.hashCode() : 0);
771 result = 31 * result + (appRoot != null ? appRoot.hashCode() : 0);
772 result = 31 * result + (inboundServices != null ? inboundServices.hashCode() : 0);
773 result = 31 * result + (precompilationEnabled ? 1 : 0);
774 result = 31 * result + (adminConsolePages != null ? adminConsolePages.hashCode() : 0);
775 result = 31 * result + (errorHandlers != null ? errorHandlers.hashCode() : 0);
776 result = 31 * result + (threadsafe ? 1 : 0);
777 result = 31 * result + (autoIdPolicy != null ? autoIdPolicy.hashCode() : 0);
778 result = 31 * result + (threadsafeValueProvided ? 1 : 0);
779 result = 31 * result + (codeLock ? 1 : 0);
780 result = 31 * result + (apiConfig != null ? apiConfig.hashCode() : 0);
781 result = 31 * result + (apiEndpointIds != null ? apiEndpointIds.hashCode() : 0);
782 result = 31 * result + (pagespeed != null ? pagespeed.hashCode() : 0);
783 result = 31 * result + (classLoaderConfig != null ? classLoaderConfig.hashCode() : 0);
784 result = 31 * result + (urlStreamHandlerType != null ? urlStreamHandlerType.hashCode() : 0);
785 result = 31 * result + (useGoogleConnectorJ.hashCode());
786 result = 31 * result + (betaSettings != null ? betaSettings.hashCode() : 0);
787 result = 31 * result + (healthCheck != null ? healthCheck.hashCode() : 0);
788 result = 31 * result + (resources != null ? resources.hashCode() : 0);
789 result = 31 * result + (network != null ? network.hashCode() : 0);
790 return result;
793 public boolean includesResource(String path) {
794 if (resourceIncludePattern == null) {
795 if (resourceFileIncludes.size() == 0) {
796 resourceIncludePattern = Pattern.compile(".*");
797 } else {
798 resourceIncludePattern = Pattern.compile(makeRegexp(resourceFileIncludes));
801 if (resourceExcludePattern == null && resourceFileExcludes.size() > 0) {
802 resourceExcludePattern = Pattern.compile(makeRegexp(resourceFileExcludes));
803 } else {
805 return includes(path, resourceIncludePattern, resourceExcludePattern);
808 public boolean includesStatic(String path) {
809 if (staticIncludePattern == null) {
810 if (staticFileIncludes.size() == 0) {
811 String staticRoot;
812 if (publicRoot.length() > 0) {
813 staticRoot = publicRoot + "/**";
814 } else {
815 staticRoot = "**";
817 staticIncludePattern = Pattern.compile(
818 makeRegexp(Collections.singletonList(staticRoot)));
819 } else {
820 List<String> patterns = new ArrayList<String>();
821 for (StaticFileInclude include : staticFileIncludes) {
822 patterns.add(include.getPattern());
824 staticIncludePattern = Pattern.compile(makeRegexp(patterns));
827 if (staticExcludePattern == null && staticFileExcludes.size() > 0) {
828 staticExcludePattern = Pattern.compile(makeRegexp(staticFileExcludes));
829 } else {
831 return includes(path, staticIncludePattern, staticExcludePattern);
835 * Tests whether {@code path} is covered by the pattern {@code includes}
836 * while not being blocked by matching {@code excludes}.
838 * @param path a URL to test
839 * @param includes a non-{@code null} pattern for included URLs
840 * @param excludes a pattern for exclusion, or {@code null} to not exclude
841 * anything from the {@code includes} set.
843 public boolean includes(String path, Pattern includes, Pattern excludes) {
844 assert(includes != null);
845 if (!includes.matcher(path).matches()) {
846 return false;
848 if (excludes != null && excludes.matcher(path).matches()) {
849 return false;
851 return true;
854 public String makeRegexp(List<String> patterns) {
855 StringBuilder builder = new StringBuilder();
856 boolean first = true;
857 for (String item : patterns) {
858 if (first) {
859 first = false;
860 } else {
861 builder.append('|');
864 while (item.charAt(0) == '/') {
865 item = item.substring(1);
868 builder.append('(');
869 if (appRoot != null) {
870 builder.append(makeFileRegex(appRoot));
872 builder.append("/");
873 builder.append(makeFileRegex(item));
874 builder.append(')');
876 return builder.toString();
880 * Helper method to translate from appengine-web.xml "file globs" to
881 * proper regular expressions as used in app.yaml.
883 * @param fileGlob the glob to translate
884 * @return the regular expression string matching the input {@code file} pattern.
886 static String makeFileRegex(String fileGlob) {
887 fileGlob = fileGlob.replaceAll("([^A-Za-z0-9\\-_/])", "\\\\$1");
888 fileGlob = fileGlob.replaceAll("\\\\\\*\\\\\\*", ".*");
889 fileGlob = fileGlob.replaceAll("\\\\\\*", "[^/]*");
890 return fileGlob;
893 * Sets the application root directory, as a prefix for the regexps in
894 * {@link #includeResourcePattern(String)} and friends. This is needed
895 * because we want to match complete filenames relative to root.
897 * @param appRoot
899 public void setSourcePrefix(String appRoot) {
900 this.appRoot = appRoot;
901 this.resourceIncludePattern = null;
902 this.resourceExcludePattern = null;
903 this.staticIncludePattern = null;
904 this.staticExcludePattern = null;
907 public String getSourcePrefix() {
908 return this.appRoot;
911 private static String toNullIfEmptyOrWhitespace(String string) {
912 if (string == null || CharMatcher.WHITESPACE.matchesAllOf(string)) {
913 return null;
915 return string;
919 * Represents a {@link java.security.Permission} that needs to be
920 * granted to user code.
922 private static class UserPermission {
923 private final String className;
924 private final String name;
925 private final String actions;
927 private boolean hasHashCode = false;
928 private int hashCode;
930 public UserPermission(String className, String name, String actions) {
931 this.className = className;
932 this.name = name;
933 this.actions = actions;
936 public String getClassName() {
937 return className;
940 public String getName() {
941 return name;
944 public String getActions() {
945 return actions;
948 @Override
949 public int hashCode() {
950 if (hasHashCode) {
951 return hashCode;
954 int hash = className.hashCode();
955 hash = 31 * hash + name.hashCode();
956 if (actions != null) {
957 hash = 31 * hash + actions.hashCode();
960 hashCode = hash;
961 hasHashCode = true;
962 return hashCode;
965 @Override
966 public boolean equals(Object obj) {
967 if (obj instanceof UserPermission) {
968 UserPermission perm = (UserPermission) obj;
969 if (className.equals(perm.className) && name.equals(perm.name)) {
970 if (actions == null ? perm.actions == null : actions.equals(perm.actions)) {
971 return true;
975 return false;
980 * Represents an &lt;include&gt; element within the
981 * &lt;static-files&gt; element. Currently this includes both a
982 * pattern and an optional expiration time specification.
984 public static class StaticFileInclude {
985 private final String pattern;
986 private final String expiration;
987 private final Map<String, String> httpHeaders;
989 public StaticFileInclude(String pattern, String expiration) {
990 this.pattern = pattern;
991 this.expiration = expiration;
992 this.httpHeaders = new LinkedHashMap<>();
995 public String getPattern() {
996 return pattern;
999 public Pattern getRegularExpression() {
1000 return Pattern.compile(makeFileRegex(pattern));
1003 public String getExpiration() {
1004 return expiration;
1007 public Map<String, String> getHttpHeaders() {
1008 return httpHeaders;
1011 @Override
1012 public int hashCode() {
1013 return Objects.hash(pattern, expiration, httpHeaders);
1016 @Override
1017 public boolean equals(Object obj) {
1018 if (!(obj instanceof StaticFileInclude)) {
1019 return false;
1022 StaticFileInclude other = (StaticFileInclude) obj;
1024 if (pattern != null) {
1025 if (!pattern.equals(other.pattern)) {
1026 return false;
1028 } else {
1029 if (other.pattern != null) {
1030 return false;
1034 if (expiration != null) {
1035 if (!expiration.equals(other.expiration)) {
1036 return false;
1038 } else {
1039 if (other.expiration != null) {
1040 return false;
1044 if (httpHeaders != null) {
1045 if (!httpHeaders.equals(other.httpHeaders)) {
1046 return false;
1048 } else {
1049 if (other.httpHeaders != null) {
1050 return false;
1054 return true;
1058 public static class AdminConsolePage {
1059 private final String name;
1060 private final String url;
1062 public AdminConsolePage(String name, String url) {
1063 this.name = name;
1064 this.url = url;
1067 public String getName() {
1068 return name;
1071 public String getUrl() {
1072 return url;
1075 @Override
1076 public int hashCode() {
1077 final int prime = 31;
1078 int result = 1;
1079 result = prime * result + ((name == null) ? 0 : name.hashCode());
1080 result = prime * result + ((url == null) ? 0 : url.hashCode());
1081 return result;
1084 @Override
1085 public boolean equals(Object obj) {
1086 if (this == obj) return true;
1087 if (obj == null) return false;
1088 if (getClass() != obj.getClass()) return false;
1089 AdminConsolePage other = (AdminConsolePage) obj;
1090 if (name == null) {
1091 if (other.name != null) return false;
1092 } else if (!name.equals(other.name)) return false;
1093 if (url == null) {
1094 if (other.url != null) return false;
1095 } else if (!url.equals(other.url)) return false;
1096 return true;
1101 * Represents an &lt;error-handler&gt; element. Currently this includes both
1102 * a file name and an optional error code.
1104 public static class ErrorHandler {
1105 private final String file;
1106 private final String errorCode;
1108 public ErrorHandler(String file, String errorCode) {
1109 this.file = file;
1110 this.errorCode = errorCode;
1113 public String getFile() {
1114 return file;
1117 public String getErrorCode() {
1118 return errorCode;
1121 @Override
1122 public int hashCode() {
1123 final int prime = 31;
1124 int result = 1;
1125 result = prime * result + ((file == null) ? 0 : file.hashCode());
1126 result = prime * result +
1127 ((errorCode == null) ? 0 : errorCode.hashCode());
1128 return result;
1131 @Override
1132 public boolean equals(Object obj) {
1133 if (!(obj instanceof ErrorHandler)) {
1134 return false;
1137 ErrorHandler handler = (ErrorHandler) obj;
1138 if (!file.equals(handler.file)) {
1139 return false;
1142 if (errorCode == null) {
1143 if (handler.errorCode != null) {
1144 return false;
1146 } else {
1147 if (!errorCode.equals(handler.errorCode)) {
1148 return false;
1152 return true;
1157 * Represents an &lt;api-config&gt; element. This is a singleton specifying
1158 * url-pattern and servlet-class for the api config server.
1160 public static class ApiConfig {
1161 private final String servletClass;
1162 private final String url;
1164 public ApiConfig(String servletClass, String url) {
1165 this.servletClass = servletClass;
1166 this.url = url;
1169 public String getservletClass() {
1170 return servletClass;
1173 public String getUrl() {
1174 return url;
1177 @Override
1178 public int hashCode() {
1179 final int prime = 31;
1180 int result = 1;
1181 result = prime * result + ((servletClass == null) ? 0 : servletClass.hashCode());
1182 result = prime * result + ((url == null) ? 0 : url.hashCode());
1183 return result;
1186 @Override
1187 public boolean equals(Object obj) {
1188 if (this == obj) { return true; }
1189 if (obj == null) { return false; }
1190 if (getClass() != obj.getClass()) { return false; }
1191 ApiConfig other = (ApiConfig) obj;
1192 if (servletClass == null) {
1193 if (other.servletClass != null) { return false; }
1194 } else if (!servletClass.equals(other.servletClass)) { return false; }
1195 if (url == null) {
1196 if (other.url != null) { return false; }
1197 } else if (!url.equals(other.url)) { return false; }
1198 return true;
1201 @Override
1202 public String toString() {
1203 return "ApiConfig{servletClass=\"" + servletClass + "\", url=\"" + url + "\"}";
1208 * Holder for automatic settings.
1210 public static class AutomaticScaling {
1211 private static final AutomaticScaling EMPTY_SETTINGS = new AutomaticScaling();
1213 public static final String AUTOMATIC = "automatic";
1214 private String minPendingLatency;
1215 private String maxPendingLatency;
1216 private String minIdleInstances;
1217 private String maxIdleInstances;
1218 private String maxConcurrentRequests;
1220 private Integer minNumInstances;
1221 private Integer maxNumInstances;
1222 private Integer coolDownPeriodSec;
1223 private CpuUtilization cpuUtilization;
1225 private Integer targetNetworkSentBytesPerSec;
1226 private Integer targetNetworkSentPacketsPerSec;
1227 private Integer targetNetworkReceivedBytesPerSec;
1228 private Integer targetNetworkReceivedPacketsPerSec;
1229 private Integer targetDiskWriteBytesPerSec;
1230 private Integer targetDiskWriteOpsPerSec;
1231 private Integer targetDiskReadBytesPerSec;
1232 private Integer targetDiskReadOpsPerSec;
1233 private Integer targetRequestCountPerSec;
1234 private Integer targetConcurrentRequests;
1236 public String getMinPendingLatency() {
1237 return minPendingLatency;
1241 * Sets minPendingLatency. Normalizes empty and null inputs to null.
1243 public void setMinPendingLatency(String minPendingLatency) {
1244 this.minPendingLatency = toNullIfEmptyOrWhitespace(minPendingLatency);
1247 public String getMaxPendingLatency() {
1248 return maxPendingLatency;
1252 * Sets maxPendingLatency. Normalizes empty and null inputs to null.
1254 public void setMaxPendingLatency(String maxPendingLatency) {
1255 this.maxPendingLatency = toNullIfEmptyOrWhitespace(maxPendingLatency);
1258 public String getMinIdleInstances() {
1259 return minIdleInstances;
1263 * Sets minIdleInstances. Normalizes empty and null inputs to null.
1265 public void setMinIdleInstances(String minIdleInstances) {
1266 this.minIdleInstances = toNullIfEmptyOrWhitespace(minIdleInstances);
1269 public String getMaxIdleInstances() {
1270 return maxIdleInstances;
1274 * Sets maxIdleInstances. Normalizes empty and null inputs to null.
1276 public void setMaxIdleInstances(String maxIdleInstances) {
1277 this.maxIdleInstances = toNullIfEmptyOrWhitespace(maxIdleInstances);
1280 public boolean isEmpty() {
1281 return this.equals(EMPTY_SETTINGS);
1284 public String getMaxConcurrentRequests() {
1285 return maxConcurrentRequests;
1289 * Sets maxConcurrentRequests. Normalizes empty and null inputs to null.
1291 public void setMaxConcurrentRequests(String maxConcurrentRequests) {
1292 this.maxConcurrentRequests = toNullIfEmptyOrWhitespace(maxConcurrentRequests);
1295 public Integer getMinNumInstances() {
1296 return minNumInstances;
1299 public void setMinNumInstances(Integer minNumInstances) {
1300 this.minNumInstances = minNumInstances;
1303 public Integer getMaxNumInstances() {
1304 return maxNumInstances;
1307 public void setMaxNumInstances(Integer maxNumInstances) {
1308 this.maxNumInstances = maxNumInstances;
1311 public Integer getCoolDownPeriodSec() {
1312 return coolDownPeriodSec;
1315 public void setCoolDownPeriodSec(Integer coolDownPeriodSec) {
1316 this.coolDownPeriodSec = coolDownPeriodSec;
1319 public CpuUtilization getCpuUtilization() {
1320 return cpuUtilization;
1323 public void setCpuUtilization(CpuUtilization cpuUtilization) {
1324 this.cpuUtilization = cpuUtilization;
1327 public Integer getTargetNetworkSentBytesPerSec() {
1328 return targetNetworkSentBytesPerSec;
1331 public void setTargetNetworkSentBytesPerSec(Integer targetNetworkSentBytesPerSec) {
1332 this.targetNetworkSentBytesPerSec = targetNetworkSentBytesPerSec;
1335 public Integer getTargetNetworkSentPacketsPerSec() {
1336 return targetNetworkSentPacketsPerSec;
1339 public void setTargetNetworkSentPacketsPerSec(Integer targetNetworkSentPacketsPerSec) {
1340 this.targetNetworkSentPacketsPerSec = targetNetworkSentPacketsPerSec;
1343 public Integer getTargetNetworkReceivedBytesPerSec() {
1344 return targetNetworkReceivedBytesPerSec;
1347 public void setTargetNetworkReceivedBytesPerSec(Integer targetNetworkReceivedBytesPerSec) {
1348 this.targetNetworkReceivedBytesPerSec = targetNetworkReceivedBytesPerSec;
1351 public Integer getTargetNetworkReceivedPacketsPerSec() {
1352 return targetNetworkReceivedPacketsPerSec;
1355 public void setTargetNetworkReceivedPacketsPerSec(Integer targetNetworkReceivedPacketsPerSec) {
1356 this.targetNetworkReceivedPacketsPerSec = targetNetworkReceivedPacketsPerSec;
1359 public Integer getTargetDiskWriteBytesPerSec() {
1360 return targetDiskWriteBytesPerSec;
1363 public void setTargetDiskWriteBytesPerSec(Integer targetDiskWriteBytesPerSec) {
1364 this.targetDiskWriteBytesPerSec = targetDiskWriteBytesPerSec;
1367 public Integer getTargetDiskWriteOpsPerSec() {
1368 return targetDiskWriteOpsPerSec;
1371 public void setTargetDiskWriteOpsPerSec(Integer targetDiskWriteOpsPerSec) {
1372 this.targetDiskWriteOpsPerSec = targetDiskWriteOpsPerSec;
1375 public Integer getTargetDiskReadBytesPerSec() {
1376 return targetDiskReadBytesPerSec;
1379 public void setTargetDiskReadBytesPerSec(Integer targetDiskReadBytesPerSec) {
1380 this.targetDiskReadBytesPerSec = targetDiskReadBytesPerSec;
1383 public Integer getTargetDiskReadOpsPerSec() {
1384 return targetDiskReadOpsPerSec;
1387 public void setTargetDiskReadOpsPerSec(Integer targetDiskReadOpsPerSec) {
1388 this.targetDiskReadOpsPerSec = targetDiskReadOpsPerSec;
1391 public Integer getTargetRequestCountPerSec() {
1392 return targetRequestCountPerSec;
1395 public void setTargetRequestCountPerSec(Integer targetRequestCountPerSec) {
1396 this.targetRequestCountPerSec = targetRequestCountPerSec;
1399 public Integer getTargetConcurrentRequests() {
1400 return targetConcurrentRequests;
1403 public void setTargetConcurrentRequests(Integer targetConcurrentRequests) {
1404 this.targetConcurrentRequests = targetConcurrentRequests;
1407 @Override
1408 public int hashCode() {
1409 return Objects.hash(maxPendingLatency, minPendingLatency, maxIdleInstances,
1410 minIdleInstances, maxConcurrentRequests, minNumInstances,
1411 maxNumInstances, coolDownPeriodSec, cpuUtilization,
1412 targetNetworkSentBytesPerSec, targetNetworkSentPacketsPerSec,
1413 targetNetworkReceivedBytesPerSec, targetNetworkReceivedPacketsPerSec,
1414 targetDiskWriteBytesPerSec, targetDiskWriteOpsPerSec,
1415 targetDiskReadBytesPerSec, targetDiskReadOpsPerSec,
1416 targetRequestCountPerSec, targetConcurrentRequests);
1419 @Override
1420 public boolean equals(Object obj) {
1421 if (this == obj) {
1422 return true;
1424 if (obj == null) {
1425 return false;
1427 if (getClass() != obj.getClass()) {
1428 return false;
1430 AutomaticScaling other = (AutomaticScaling) obj;
1431 return Objects.equals(maxPendingLatency, other.maxPendingLatency)
1432 && Objects.equals(minPendingLatency, other.minPendingLatency)
1433 && Objects.equals(maxIdleInstances, other.maxIdleInstances)
1434 && Objects.equals(minIdleInstances, other.minIdleInstances)
1435 && Objects.equals(maxConcurrentRequests, other.maxConcurrentRequests)
1436 && Objects.equals(minNumInstances, other.minNumInstances)
1437 && Objects.equals(maxNumInstances, other.maxNumInstances)
1438 && Objects.equals(coolDownPeriodSec, other.coolDownPeriodSec)
1439 && Objects.equals(cpuUtilization, other.cpuUtilization)
1440 && Objects.equals(targetNetworkSentBytesPerSec, other.targetNetworkSentBytesPerSec)
1441 && Objects.equals(targetNetworkSentPacketsPerSec, other.targetNetworkSentPacketsPerSec)
1442 && Objects.equals(targetNetworkReceivedBytesPerSec,
1443 other.targetNetworkReceivedBytesPerSec)
1444 && Objects.equals(targetNetworkReceivedPacketsPerSec,
1445 other.targetNetworkReceivedPacketsPerSec)
1446 && Objects.equals(targetDiskWriteBytesPerSec, other.targetDiskWriteBytesPerSec)
1447 && Objects.equals(targetDiskWriteOpsPerSec, other.targetDiskWriteOpsPerSec)
1448 && Objects.equals(targetDiskReadBytesPerSec, other.targetDiskReadBytesPerSec)
1449 && Objects.equals(targetDiskReadOpsPerSec, other.targetDiskReadOpsPerSec)
1450 && Objects.equals(targetRequestCountPerSec, other.targetRequestCountPerSec)
1451 && Objects.equals(targetConcurrentRequests, other.targetConcurrentRequests);
1454 @Override
1455 public String toString() {
1456 return "AutomaticScaling [minPendingLatency=" + minPendingLatency
1457 + ", maxPendingLatency=" + maxPendingLatency
1458 + ", minIdleInstances=" + minIdleInstances
1459 + ", maxIdleInstances=" + maxIdleInstances
1460 + ", maxConcurrentRequests=" + maxConcurrentRequests
1461 + ", minNumInstances=" + minNumInstances
1462 + ", maxNumInstances=" + maxNumInstances
1463 + ", coolDownPeriodSec=" + coolDownPeriodSec
1464 + ", cpuUtilization=" + cpuUtilization
1465 + ", targetNetworkSentBytesPerSec=" + targetNetworkSentBytesPerSec
1466 + ", targetNetworkSentPacketsPerSec=" + targetNetworkSentPacketsPerSec
1467 + ", targetNetworkReceivedBytesPerSec=" + targetNetworkReceivedBytesPerSec
1468 + ", targetNetworkReceivedPacketsPerSec=" + targetNetworkReceivedPacketsPerSec
1469 + ", targetDiskWriteBytesPerSec=" + targetDiskWriteBytesPerSec
1470 + ", targetDiskWriteOpsPerSec=" + targetDiskWriteOpsPerSec
1471 + ", targetDiskReadBytesPerSec=" + targetDiskReadBytesPerSec
1472 + ", targetDiskReadOpsPerSec=" + targetDiskReadOpsPerSec
1473 + ", targetRequestCountPerSec=" + targetRequestCountPerSec
1474 + ", targetConcurrentRequests=" + targetConcurrentRequests
1475 + "]";
1480 * Holder for CPU utilization.
1482 public static class CpuUtilization {
1483 private static final CpuUtilization EMPTY_SETTINGS = new CpuUtilization();
1484 private Double targetUtilization;
1485 private Integer aggregationWindowLengthSec;
1487 public Double getTargetUtilization() {
1488 return targetUtilization;
1491 public void setTargetUtilization(Double targetUtilization) {
1492 this.targetUtilization = targetUtilization;
1495 public Integer getAggregationWindowLengthSec() {
1496 return aggregationWindowLengthSec;
1499 public void setAggregationWindowLengthSec(Integer aggregationWindowLengthSec) {
1500 this.aggregationWindowLengthSec = aggregationWindowLengthSec;
1503 public boolean isEmpty() {
1504 return this.equals(EMPTY_SETTINGS);
1507 @Override
1508 public int hashCode() {
1509 return Objects.hash(targetUtilization, aggregationWindowLengthSec);
1512 @Override
1513 public boolean equals(Object obj) {
1514 if (this == obj) {
1515 return true;
1517 if (obj == null) {
1518 return false;
1520 if (getClass() != obj.getClass()) {
1521 return false;
1523 CpuUtilization other = (CpuUtilization) obj;
1524 return Objects.equals(targetUtilization, other.targetUtilization)
1525 && Objects.equals(aggregationWindowLengthSec, other.aggregationWindowLengthSec);
1528 @Override
1529 public String toString() {
1530 return "CpuUtilization [targetUtilization=" + targetUtilization
1531 + ", aggregationWindowLengthSec=" + aggregationWindowLengthSec + "]";
1536 * Holder for health check.
1538 public static class HealthCheck {
1539 private static final HealthCheck EMPTY_SETTINGS = new HealthCheck();
1541 private boolean enableHealthCheck = true;
1542 private Integer checkIntervalSec;
1543 private Integer timeoutSec;
1544 private Integer unhealthyThreshold;
1545 private Integer healthyThreshold;
1546 private Integer restartThreshold;
1547 private String host;
1549 public boolean getEnableHealthCheck() {
1550 return enableHealthCheck;
1553 * Sets enableHealthCheck.
1555 public void setEnableHealthCheck(boolean enableHealthCheck) {
1556 this.enableHealthCheck = enableHealthCheck;
1559 public Integer getCheckIntervalSec() {
1560 return checkIntervalSec;
1563 * Sets checkIntervalSec.
1565 public void setCheckIntervalSec(Integer checkIntervalSec) {
1566 this.checkIntervalSec = checkIntervalSec;
1569 public Integer getTimeoutSec() {
1570 return timeoutSec;
1573 * Sets timeoutSec.
1575 public void setTimeoutSec(Integer timeoutSec) {
1576 this.timeoutSec = timeoutSec;
1579 public Integer getUnhealthyThreshold() {
1580 return unhealthyThreshold;
1584 * Sets unhealthyThreshold.
1586 public void setUnhealthyThreshold(Integer unhealthyThreshold) {
1587 this.unhealthyThreshold = unhealthyThreshold;
1590 public Integer getHealthyThreshold() {
1591 return healthyThreshold;
1595 * Sets healthyThreshold.
1598 public void setHealthyThreshold(Integer healthyThreshold) {
1599 this.healthyThreshold = healthyThreshold;
1602 public Integer getRestartThreshold() {
1603 return restartThreshold;
1607 * Sets restartThreshold.
1609 public void setRestartThreshold(Integer restartThreshold) {
1610 this.restartThreshold = restartThreshold;
1613 public String getHost() {
1614 return host;
1618 * Sets host. Normalizes empty and null inputs to null.
1620 public void setHost(String host) {
1621 this.host = toNullIfEmptyOrWhitespace(host);
1624 public boolean isEmpty() {
1625 return this.equals(EMPTY_SETTINGS);
1628 @Override
1629 public int hashCode() {
1630 return Objects.hash(enableHealthCheck, checkIntervalSec, timeoutSec, unhealthyThreshold,
1631 healthyThreshold, restartThreshold, host);
1634 @Override
1635 public boolean equals(Object obj) {
1636 if (this == obj) {
1637 return true;
1639 if (obj == null) {
1640 return false;
1642 if (getClass() != obj.getClass()) {
1643 return false;
1645 HealthCheck other = (HealthCheck) obj;
1646 return Objects.equals(enableHealthCheck, other.enableHealthCheck)
1647 && Objects.equals(checkIntervalSec, other.checkIntervalSec)
1648 && Objects.equals(timeoutSec, other.timeoutSec)
1649 && Objects.equals(unhealthyThreshold, other.unhealthyThreshold)
1650 && Objects.equals(healthyThreshold, other.healthyThreshold)
1651 && Objects.equals(restartThreshold, other.restartThreshold)
1652 && Objects.equals(host, other.host);
1655 @Override
1656 public String toString() {
1657 return "HealthCheck [enableHealthCheck=" + enableHealthCheck
1658 + ", checkIntervalSec=" + checkIntervalSec
1659 + ", timeoutSec=" + timeoutSec
1660 + ", unhealthyThreshold=" + unhealthyThreshold
1661 + ", healthyThreshold=" + healthyThreshold
1662 + ", restartThreshold=" + restartThreshold
1663 + ", host=" + host + "]";
1668 * Holder for Resources
1670 public static class Resources {
1671 private static final Resources EMPTY_SETTINGS = new Resources();
1673 private double cpu;
1675 public double getCpu() {
1676 return cpu;
1679 public void setCpu(double cpu) {
1680 this.cpu = cpu;
1683 private double memory_gb;
1685 public double getMemoryGb() {
1686 return memory_gb;
1689 public void setMemoryGb(double memory_gb) {
1690 this.memory_gb = memory_gb;
1693 private int disk_size_gb;
1695 public int getDiskSizeGb() {
1696 return disk_size_gb;
1699 public void setDiskSizeGb(int disk_size_gb) {
1700 this.disk_size_gb = disk_size_gb;
1703 public boolean isEmpty() {
1704 return this.equals(EMPTY_SETTINGS);
1707 @Override
1708 public int hashCode() {
1709 return Objects.hash(cpu, memory_gb, disk_size_gb);
1712 @Override
1713 public boolean equals(Object obj) {
1714 if (this == obj) {
1715 return true;
1717 if (obj == null) {
1718 return false;
1720 if (getClass() != obj.getClass()) {
1721 return false;
1723 Resources other = (Resources) obj;
1724 return Objects.equals(cpu, other.cpu) &&
1725 Objects.equals(memory_gb, other.memory_gb) &&
1726 Objects.equals(disk_size_gb, other.disk_size_gb);
1729 @Override
1730 public String toString() {
1731 return "Resources [" + "cpu=" + cpu +
1732 ", memory_gb=" + memory_gb +
1733 ", disk_size_gb=" + disk_size_gb + "]";
1738 * Holder for network.
1740 public static class Network {
1741 private static final Network EMPTY_SETTINGS = new Network();
1743 private String instanceTag;
1745 public String getInstanceTag() {
1746 return instanceTag;
1749 public void setInstanceTag(String instanceTag) {
1750 this.instanceTag = instanceTag;
1753 private final List<String> forwardedPorts = Lists.newArrayList();
1755 public List<String> getForwardedPorts() {
1756 return Collections.unmodifiableList(forwardedPorts);
1759 public void addForwardedPort(String forwardedPort) {
1760 forwardedPorts.add(forwardedPort);
1763 private String name;
1765 public String getName() {
1766 return name;
1769 public void setName(String name) {
1770 this.name = name;
1773 public boolean isEmpty() {
1774 return this.equals(EMPTY_SETTINGS);
1777 @Override
1778 public int hashCode() {
1779 return Objects.hash(forwardedPorts, instanceTag);
1782 @Override
1783 public boolean equals(Object obj) {
1784 if (this == obj) {
1785 return true;
1787 if (obj == null) {
1788 return false;
1790 if (getClass() != obj.getClass()) {
1791 return false;
1793 Network other = (Network) obj;
1794 return Objects.equals(forwardedPorts, other.forwardedPorts)
1795 && Objects.equals(instanceTag, other.instanceTag);
1798 @Override
1799 public String toString() {
1800 return "Network [forwardedPorts=" + forwardedPorts + ", instanceTag=" + instanceTag + "]";
1805 * Holder for manual settings.
1807 public static class ManualScaling {
1808 private static final ManualScaling EMPTY_SETTINGS = new ManualScaling();
1810 private String instances;
1812 public String getInstances() {
1813 return instances;
1817 * Sets instances. Normalizes empty and null inputs to null.
1819 public void setInstances(String instances) {
1820 this.instances = toNullIfEmptyOrWhitespace(instances);
1823 public boolean isEmpty() {
1824 return this.equals(EMPTY_SETTINGS);
1827 @Override
1828 public int hashCode() {
1829 return Objects.hash(instances);
1832 @Override
1833 public boolean equals(Object obj) {
1834 if (this == obj) {
1835 return true;
1837 if (obj == null) {
1838 return false;
1840 if (getClass() != obj.getClass()) {
1841 return false;
1843 ManualScaling other = (ManualScaling) obj;
1844 return Objects.equals(instances, other.instances);
1847 @Override
1848 public String toString() {
1849 return "ManualScaling [" + "instances=" + instances + "]";
1854 * Holder for basic settings.
1856 public static class BasicScaling {
1857 private static final BasicScaling EMPTY_SETTINGS = new BasicScaling();
1859 private String maxInstances;
1860 private String idleTimeout;
1862 public String getMaxInstances() {
1863 return maxInstances;
1866 public String getIdleTimeout() {
1867 return idleTimeout;
1871 * Sets maxInstances. Normalizes empty and null inputs to null.
1873 public void setMaxInstances(String maxInstances) {
1874 this.maxInstances = toNullIfEmptyOrWhitespace(maxInstances);
1878 * Sets idleTimeout. Normalizes empty and null inputs to null.
1880 public void setIdleTimeout(String idleTimeout) {
1881 this.idleTimeout = toNullIfEmptyOrWhitespace(idleTimeout);
1884 public boolean isEmpty() {
1885 return this.equals(EMPTY_SETTINGS);
1888 @Override
1889 public int hashCode() {
1890 return Objects.hash(maxInstances, idleTimeout);
1893 @Override
1894 public boolean equals(Object obj) {
1895 if (this == obj) {
1896 return true;
1898 if (obj == null) {
1899 return false;
1901 if (getClass() != obj.getClass()) {
1902 return false;
1904 BasicScaling other = (BasicScaling) obj;
1905 return Objects.equals(maxInstances, other.maxInstances)
1906 && Objects.equals(idleTimeout, other.idleTimeout);
1909 @Override
1910 public String toString() {
1911 return "BasicScaling [" + "maxInstances=" + maxInstances
1912 + ", idleTimeout=" + idleTimeout + "]";
1917 * Represents a &lt;pagespeed&gt; element. This is used to specify configuration for the Page
1918 * Speed Service, which can be used to automatically optimize the loading speed of app engine
1919 * sites.
1921 public static class Pagespeed {
1922 private final List<String> urlBlacklist = Lists.newArrayList();
1923 private final List<String> domainsToRewrite = Lists.newArrayList();
1924 private final List<String> enabledRewriters = Lists.newArrayList();
1925 private final List<String> disabledRewriters = Lists.newArrayList();
1927 public void addUrlBlacklist(String url) {
1928 urlBlacklist.add(url);
1931 public List<String> getUrlBlacklist() {
1932 return Collections.unmodifiableList(urlBlacklist);
1935 public void addDomainToRewrite(String domain) {
1936 domainsToRewrite.add(domain);
1939 public List<String> getDomainsToRewrite() {
1940 return Collections.unmodifiableList(domainsToRewrite);
1943 public void addEnabledRewriter(String rewriter) {
1944 enabledRewriters.add(rewriter);
1947 public List<String> getEnabledRewriters() {
1948 return Collections.unmodifiableList(enabledRewriters);
1951 public void addDisabledRewriter(String rewriter) {
1952 disabledRewriters.add(rewriter);
1955 public List<String> getDisabledRewriters() {
1956 return Collections.unmodifiableList(disabledRewriters);
1959 public boolean isEmpty() {
1960 return urlBlacklist.isEmpty() && domainsToRewrite.isEmpty() && enabledRewriters.isEmpty()
1961 && disabledRewriters.isEmpty();
1964 @Override
1965 public int hashCode() {
1966 return Objects.hash(urlBlacklist, domainsToRewrite, enabledRewriters, disabledRewriters);
1969 @Override
1970 public boolean equals(Object obj) {
1971 if (this == obj) {
1972 return true;
1974 if (obj == null) {
1975 return false;
1977 if (getClass() != obj.getClass()) {
1978 return false;
1980 Pagespeed other = (Pagespeed) obj;
1981 return Objects.equals(urlBlacklist, other.urlBlacklist)
1982 && Objects.equals(domainsToRewrite, other.domainsToRewrite)
1983 && Objects.equals(enabledRewriters, other.enabledRewriters)
1984 && Objects.equals(disabledRewriters, other.disabledRewriters);
1987 @Override
1988 public String toString() {
1989 return "Pagespeed [urlBlacklist=" + urlBlacklist + ", domainsToRewrite=" + domainsToRewrite
1990 + ", enabledRewriters=" + enabledRewriters + ", disabledRewriters=" + disabledRewriters
1991 + "]";
1995 public static class ClassLoaderConfig {
1996 private final List<PrioritySpecifierEntry> entries = Lists.newArrayList();
1998 public void add(PrioritySpecifierEntry entry) {
1999 entries.add(entry);
2002 public List<PrioritySpecifierEntry> getEntries() {
2003 return entries;
2006 @Override
2007 public int hashCode() {
2008 final int prime = 31;
2009 int result = 1;
2010 result = prime * result + ((entries == null) ? 0 : entries.hashCode());
2011 return result;
2014 @Override
2015 public boolean equals(Object obj) {
2016 if (this == obj) return true;
2017 if (obj == null) return false;
2018 if (getClass() != obj.getClass()) return false;
2019 ClassLoaderConfig other = (ClassLoaderConfig) obj;
2020 if (entries == null) {
2021 if (other.entries != null) return false;
2022 } else if (!entries.equals(other.entries)) return false;
2023 return true;
2026 @Override
2027 public String toString() {
2028 return "ClassLoaderConfig{entries=\"" + entries + "\"}";
2032 public static class PrioritySpecifierEntry {
2033 private String filename;
2034 private Double priority;
2036 private void checkNotAlreadySet() {
2037 if (filename != null) {
2038 throw new AppEngineConfigException("Found more that one file name matching tag. "
2039 + "Only one of 'filename' attribute allowed.");
2043 public String getFilename() {
2044 return filename;
2047 public void setFilename(String filename) {
2048 checkNotAlreadySet();
2049 this.filename = filename;
2052 public Double getPriority() {
2053 return priority;
2056 public double getPriorityValue() {
2057 if (priority == null) {
2058 return 1.0d;
2060 return priority;
2063 public void setPriority(String priority) {
2064 if (this.priority != null) {
2065 throw new AppEngineConfigException("The 'priority' tag may only be specified once.");
2068 if (priority == null) {
2069 this.priority = null;
2070 return;
2073 this.priority = Double.parseDouble(priority);
2076 public void checkClassLoaderConfig() {
2077 if (filename == null) {
2078 throw new AppEngineConfigException("Must have a filename attribute.");
2082 @Override
2083 public int hashCode() {
2084 final int prime = 31;
2085 int result = 1;
2086 result = prime * result + ((filename == null) ? 0 : filename.hashCode());
2087 result = prime * result + ((priority == null) ? 0 : priority.hashCode());
2088 return result;
2091 @Override
2092 public boolean equals(Object obj) {
2093 if (this == obj) return true;
2094 if (obj == null) return false;
2095 if (getClass() != obj.getClass()) return false;
2096 PrioritySpecifierEntry other = (PrioritySpecifierEntry) obj;
2097 if (filename == null) {
2098 if (other.filename != null) return false;
2099 } else if (!filename.equals(other.filename)) return false;
2100 if (priority == null) {
2101 if (other.priority != null) return false;
2102 } else if (!priority.equals(other.priority)) return false;
2103 return true;
2106 @Override
2107 public String toString() {
2108 return "PrioritySpecifierEntry{filename=\"" + filename + "\", priority=\"" + priority + "\"}";