| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 |
| * |
| * http://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 org.apache.catalina.storeconfig; |
| |
| import java.io.PrintWriter; |
| import java.net.URL; |
| |
| import javax.management.MBeanServer; |
| import javax.management.MalformedObjectNameException; |
| import javax.management.ObjectName; |
| |
| import org.apache.catalina.Context; |
| import org.apache.catalina.Host; |
| import org.apache.catalina.Server; |
| import org.apache.catalina.Service; |
| import org.apache.catalina.core.StandardContext; |
| import org.apache.catalina.mbeans.MBeanUtils; |
| import org.apache.catalina.startup.Bootstrap; |
| import org.apache.juli.logging.Log; |
| import org.apache.juli.logging.LogFactory; |
| import org.apache.tomcat.util.res.StringManager; |
| |
| /** |
| * Store Server/Service/Host/Context at file or PrintWriter. Default server.xml is at $catalina.base/conf/server.xml |
| */ |
| public class StoreConfig implements IStoreConfig { |
| private static final Log log = LogFactory.getLog(StoreConfig.class); |
| protected static final StringManager sm = StringManager.getManager(Constants.Package); |
| |
| private String serverFilename = "conf/server.xml"; |
| |
| private StoreRegistry registry; |
| |
| private Server server; |
| |
| /** |
| * Get server.xml location |
| * |
| * @return The server file name |
| */ |
| public String getServerFilename() { |
| return serverFilename; |
| } |
| |
| /** |
| * Set new server.xml location. |
| * |
| * @param string The server.xml location |
| */ |
| public void setServerFilename(String string) { |
| serverFilename = string; |
| } |
| |
| @Override |
| public StoreRegistry getRegistry() { |
| return registry; |
| } |
| |
| @Override |
| public void setServer(Server aServer) { |
| server = aServer; |
| } |
| |
| @Override |
| public Server getServer() { |
| return server; |
| } |
| |
| @Override |
| public void setRegistry(StoreRegistry aRegistry) { |
| registry = aRegistry; |
| } |
| |
| @Override |
| public void storeConfig() { |
| store(server); |
| } |
| |
| /** |
| * Store Server from Object Name (Catalina:type=Server). |
| * |
| * @param aServerName Server ObjectName |
| * @param backup <code>true</code> to backup existing configuration files before rewriting them |
| * @param externalAllowed <code>true</code> to allow saving webapp configuration for webapps that are not inside the |
| * host's app directory |
| * |
| * @throws MalformedObjectNameException Bad MBean name |
| */ |
| public synchronized void storeServer(String aServerName, boolean backup, boolean externalAllowed) |
| throws MalformedObjectNameException { |
| if (aServerName == null || aServerName.isEmpty()) { |
| log.error(sm.getString("config.emptyObjectName")); |
| return; |
| } |
| MBeanServer mserver = MBeanUtils.createServer(); |
| ObjectName objectName = new ObjectName(aServerName); |
| if (mserver.isRegistered(objectName)) { |
| try { |
| Server aServer = (Server) mserver.getAttribute(objectName, "managedResource"); |
| StoreDescription desc = getRegistry().findDescription(StandardContext.class); |
| if (desc != null) { |
| boolean oldSeparate = desc.isStoreSeparate(); |
| boolean oldBackup = desc.isBackup(); |
| boolean oldExternalAllowed = desc.isExternalAllowed(); |
| try { |
| desc.setStoreSeparate(true); |
| desc.setBackup(backup); |
| desc.setExternalAllowed(externalAllowed); |
| store(aServer); |
| } finally { |
| desc.setStoreSeparate(oldSeparate); |
| desc.setBackup(oldBackup); |
| desc.setExternalAllowed(oldExternalAllowed); |
| } |
| } else { |
| store(aServer); |
| } |
| } catch (Exception e) { |
| log.error(sm.getString("config.storeServerError"), e); |
| } |
| } else { |
| log.info(sm.getString("config.objectNameNotFound", aServerName)); |
| } |
| } |
| |
| /** |
| * Store a Context from ObjectName. |
| * |
| * @param aContextName MBean ObjectName |
| * @param backup <code>true</code> to backup existing configuration files before rewriting them |
| * @param externalAllowed <code>true</code> to allow saving webapp configuration for webapps that are not inside the |
| * host's app directory |
| * |
| * @throws MalformedObjectNameException Bad MBean name |
| */ |
| public synchronized void storeContext(String aContextName, boolean backup, boolean externalAllowed) |
| throws MalformedObjectNameException { |
| if (aContextName == null || aContextName.isEmpty()) { |
| log.error(sm.getString("config.emptyObjectName")); |
| return; |
| } |
| MBeanServer mserver = MBeanUtils.createServer(); |
| ObjectName objectName = new ObjectName(aContextName); |
| if (mserver.isRegistered(objectName)) { |
| try { |
| Context aContext = (Context) mserver.getAttribute(objectName, "managedResource"); |
| URL configFile = aContext.getConfigFile(); |
| if (configFile != null) { |
| StoreDescription desc = getRegistry().findDescription(aContext.getClass()); |
| if (desc != null) { |
| boolean oldSeparate = desc.isStoreSeparate(); |
| boolean oldBackup = desc.isBackup(); |
| boolean oldExternalAllowed = desc.isExternalAllowed(); |
| try { |
| desc.setStoreSeparate(true); |
| desc.setBackup(backup); |
| desc.setExternalAllowed(externalAllowed); |
| desc.getStoreFactory().store(null, -2, aContext); |
| } finally { |
| desc.setStoreSeparate(oldSeparate); |
| desc.setBackup(oldBackup); |
| desc.setBackup(oldExternalAllowed); |
| } |
| } |
| } else { |
| log.error(sm.getString("config.missingContextFile", aContext.getPath())); |
| } |
| } catch (Exception e) { |
| log.error(sm.getString("config.storeContextError", aContextName), e); |
| } |
| } else { |
| log.info(sm.getString("config.objectNameNotFound", aContextName)); |
| } |
| } |
| |
| @Override |
| public synchronized boolean store(Server aServer) { |
| StoreFileMover mover = |
| new StoreFileMover(Bootstrap.getCatalinaBase(), getServerFilename(), getRegistry().getEncoding()); |
| // Open an output writer for the new configuration file |
| try { |
| try (PrintWriter writer = mover.getWriter()) { |
| store(writer, -2, aServer); |
| } |
| mover.move(); |
| return true; |
| } catch (Exception e) { |
| log.error(sm.getString("config.storeServerError"), e); |
| } |
| return false; |
| } |
| |
| @Override |
| public synchronized boolean store(Context aContext) { |
| try { |
| StoreDescription desc = getRegistry().findDescription(aContext.getClass()); |
| if (desc != null) { |
| boolean old = desc.isStoreSeparate(); |
| try { |
| desc.setStoreSeparate(true); |
| desc.getStoreFactory().store(null, -2, aContext); |
| } finally { |
| desc.setStoreSeparate(old); |
| } |
| } |
| return true; |
| } catch (Exception e) { |
| log.error(sm.getString("config.storeContextError", aContext.getName()), e); |
| } |
| return false; |
| } |
| |
| @Override |
| public void store(PrintWriter aWriter, int indent, Context aContext) throws Exception { |
| boolean oldSeparate = true; |
| StoreDescription desc = null; |
| try { |
| desc = getRegistry().findDescription(aContext.getClass()); |
| if (desc != null) { |
| oldSeparate = desc.isStoreSeparate(); |
| desc.setStoreSeparate(false); |
| desc.getStoreFactory().store(aWriter, indent, aContext); |
| } |
| } finally { |
| if (desc != null) { |
| desc.setStoreSeparate(oldSeparate); |
| } else { |
| log.warn(sm.getString("factory.storeNoDescriptor", aContext.getClass())); |
| } |
| } |
| } |
| |
| @Override |
| public void store(PrintWriter aWriter, int indent, Host aHost) throws Exception { |
| StoreDescription desc = getRegistry().findDescription(aHost.getClass()); |
| if (desc != null) { |
| desc.getStoreFactory().store(aWriter, indent, aHost); |
| } else { |
| log.warn(sm.getString("factory.storeNoDescriptor", aHost.getClass())); |
| } |
| } |
| |
| @Override |
| public void store(PrintWriter aWriter, int indent, Service aService) throws Exception { |
| StoreDescription desc = getRegistry().findDescription(aService.getClass()); |
| if (desc != null) { |
| desc.getStoreFactory().store(aWriter, indent, aService); |
| } else { |
| log.warn(sm.getString("factory.storeNoDescriptor", aService.getClass())); |
| } |
| } |
| |
| @Override |
| public void store(PrintWriter writer, int indent, Server aServer) throws Exception { |
| StoreDescription desc = getRegistry().findDescription(aServer.getClass()); |
| if (desc != null) { |
| desc.getStoreFactory().store(writer, indent, aServer); |
| } else { |
| log.warn(sm.getString("factory.storeNoDescriptor", aServer.getClass())); |
| } |
| } |
| |
| } |