All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.appengine.tools.development.SharedMain Maven / Gradle / Ivy

Go to download

SDK for dev_appserver (local development) with some of the dependencies shaded (repackaged)

There is a newer version: 2.0.31
Show newest version
/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.appengine.tools.development;

import com.google.appengine.tools.info.AppengineSdk;
import com.google.appengine.tools.util.Logging;
import com.google.appengine.tools.util.Option;
import com.google.apphosting.utils.config.AppEngineWebXml;
import com.google.apphosting.utils.config.AppEngineWebXmlReader;
import com.google.appengine.repackaged.com.google.common.annotations.VisibleForTesting;
import com.google.appengine.repackaged.com.google.common.collect.ImmutableList;
import java.awt.Toolkit;
import java.io.File;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.TimeZone;

/**
 * Contains operations common to the {@linkplain DevAppServerMain Java dev app server startup} and
 * the {@linkplain com.google.appengine.tools.development.devappserver2.StandaloneInstance
 * devappserver2 subprocess instance}.
 */
public abstract class SharedMain {

  private static String originalTimeZone;

  private boolean disableRestrictedCheck = false;
  private String runtime = null;
  private List propertyOptions = null;

  /**
   * Returns the list of built-in {@link Option Options} that apply to both the monolithic dev app
   * server (in the Java SDK) and instances running under the Python devappserver2.
   */
  protected List

We need this information later, so that we can know if the user actually requested an * override of the timezone. We can still be wrong about this, for example, if someone directly or * indirectly calls {@code TimeZone.getDefault} before the main method to this class. This doesn't * happen in the App Engine tools themselves, but might theoretically happen in some third-party * tool that wraps the App Engine tools. In that case, they can set {@code * appengine.user.timezone} to override what we're inferring for user.timezone. */ private static void recordTimeZone() { originalTimeZone = System.getProperty("user.timezone"); // For some reasons, java8/11 default to "" and Java17 to null, so we keep default to empty // which is the value handled later. if (originalTimeZone == null) { originalTimeZone = ""; } } protected abstract void printHelp(PrintStream out); protected void postServerActions(Map stringProperties) { // TODO Consider reading properties from a file, or // parsing an Option. setTimeZone(stringProperties); if (disableRestrictedCheck) { stringProperties.put("appengine.disableRestrictedCheck", ""); } } protected void addPropertyOptionToProperties(Map properties) { properties.putAll(parsePropertiesList(propertyOptions)); } protected Map getSystemProperties() { Properties properties = System.getProperties(); // We do not expect that the system properties will contain non-String keys or values, // but check just in case. for (Map.Entry entry : properties.entrySet()) { if (!(entry.getKey() instanceof String) || !(entry.getValue() instanceof String)) { throw new IllegalArgumentException("Non-string property " + entry.getKey()); } } @SuppressWarnings({"rawtypes", "unchecked"}) Map stringProperties = (Map) (Map) properties; return Collections.checkedMap(stringProperties, String.class, String.class); } private void setTimeZone(Map serviceProperties) { String timeZone = serviceProperties.get("appengine.user.timezone"); if (timeZone != null) { TimeZone.setDefault(TimeZone.getTimeZone(timeZone)); } else { timeZone = originalTimeZone; } serviceProperties.put("appengine.user.timezone.impl", timeZone); } public void validateWarPath(File war) { if (!war.exists()) { System.out.println("Unable to find the webapp directory " + war); printHelp(System.err); System.exit(1); } else if (!war.isDirectory()) { System.out.println("dev_appserver only accepts webapp directories, not war files."); printHelp(System.err); System.exit(1); } } /** * Calculate which runtime should be used for this local SDK execution. Can be Java8. The * information may come from the --runtime flag or appengine-web.xml or the lack of web.xml. */ protected void configureRuntime(File appDirectory) { if (runtime != null) { return; } AppEngineWebXml appEngineWebXml = new AppEngineWebXmlReader(appDirectory.getAbsolutePath()).readAppEngineWebXml(); runtime = appEngineWebXml.getRuntime(); if (runtime == null) { runtime = "java8"; // Default. } if (runtime.equals("java7")) { throw new IllegalArgumentException("the Java7 runtime is not supported anymore."); } if (Objects.equals(runtime, "java21")) { System.setProperty("appengine.use.EE8", "true"); AppengineSdk.resetSdk(); } sharedInit(); } protected String getRuntime() { return runtime; } /** * Parse the properties list. Each string in the last may take the form: name=value name shorthand * for name=true noname shorthand for name=false name= required syntax to specify an empty value * * @param properties A list of unparsed properties (may be null). * @return A map from property names to values. */ @VisibleForTesting static Map parsePropertiesList(List properties) { Map parsedProperties = new HashMap<>(); if (properties != null) { for (String property : properties) { String[] propertyKeyValue = property.split("=", 2); if (propertyKeyValue.length == 2) { parsedProperties.put(propertyKeyValue[0], propertyKeyValue[1]); } else if (propertyKeyValue[0].startsWith("no")) { parsedProperties.put(propertyKeyValue[0].substring(2), "false"); } else { parsedProperties.put(propertyKeyValue[0], "true"); } } } return parsedProperties; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy