Clarify CMS initialisation
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 18 Jul 2022 13:59:51 +0000 (15:59 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 18 Jul 2022 13:59:51 +0000 (15:59 +0200)
21 files changed:
org.argeo.api.cms/src/org/argeo/api/cms/CmsConstants.java
org.argeo.cms/OSGI-INF/acrContentRepository.xml [deleted file]
org.argeo.cms/OSGI-INF/cmsAcrHttpHandler.xml
org.argeo.cms/OSGI-INF/cmsContentRepository.xml [new file with mode: 0644]
org.argeo.cms/OSGI-INF/cmsDeployment.xml
org.argeo.cms/OSGI-INF/cmsOsgiLogger.xml [new file with mode: 0644]
org.argeo.cms/OSGI-INF/cmsUserAdmin.xml [new file with mode: 0644]
org.argeo.cms/OSGI-INF/deployConfig.xml [deleted file]
org.argeo.cms/OSGI-INF/nodeUserAdmin.xml [deleted file]
org.argeo.cms/OSGI-INF/simpleTransactionManager.xml [deleted file]
org.argeo.cms/OSGI-INF/transactionManager.xml [new file with mode: 0644]
org.argeo.cms/bnd.bnd
org.argeo.cms/build.properties
org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java [deleted file]
org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsActivator.java
org.argeo.cms/src/org/argeo/cms/internal/osgi/CmsOsgiLogger.java
org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/osgi/NodeUserAdmin.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsStateImpl.java

index 7b89813fd32c56845f03e71e247e0515ea11edc5..578c82431d8362fc711c939c968d686258cfb645 100644 (file)
@@ -79,6 +79,11 @@ public interface CmsConstants {
         */
        String NODE_SERVICE = NODE;
 
+       /*
+        * COMPONENT PROPERTIES
+        */
+       String CONTEXT_PATH = "context.path";
+
        /*
         * INIT FRAMEWORK PROPERTIES
         */
diff --git a/org.argeo.cms/OSGI-INF/acrContentRepository.xml b/org.argeo.cms/OSGI-INF/acrContentRepository.xml
deleted file mode 100644 (file)
index b7a13b4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="true" name="ACR Content Repository">
-   <implementation class="org.argeo.cms.internal.runtime.DeployedContentRepository"/>
-   <reference bind="addProvider" cardinality="0..n" interface="org.argeo.api.acr.spi.ContentProvider" name="ContentProvider" policy="dynamic" />
-   <service>
-      <provide interface="org.argeo.api.acr.ContentRepository"/>
-      <provide interface="org.argeo.api.acr.spi.ProvidedRepository"/>
-   </service>
-   <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
-   <reference bind="setUuidFactory" cardinality="1..1" interface="org.argeo.api.uuid.UuidFactory" name="UuidFactory" policy="static"/>
-   <reference bind="setUserManager" cardinality="1..1" interface="org.argeo.cms.CmsUserManager" name="CmsUserManager" policy="static"/>
-</scr:component>
index 0a2684a3d8e3b86f3acf8fce22d7c059f18c4566..dc45b027e6223d7f0e9c69763314e43896643377 100644 (file)
@@ -3,6 +3,6 @@
    <implementation class="org.argeo.cms.internal.runtime.CmsAcrHttpHandler"/>
    <service>
       <provide interface="com.sun.net.httpserver.HttpHandler"/>
-      <property name="contextPath" type="String" value="/api/acr" />
+      <property name="context.path" type="String" value="/api/acr" />
    </service>
 </scr:component>
diff --git a/org.argeo.cms/OSGI-INF/cmsContentRepository.xml b/org.argeo.cms/OSGI-INF/cmsContentRepository.xml
new file mode 100644 (file)
index 0000000..b7a13b4
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="true" name="ACR Content Repository">
+   <implementation class="org.argeo.cms.internal.runtime.DeployedContentRepository"/>
+   <reference bind="addProvider" cardinality="0..n" interface="org.argeo.api.acr.spi.ContentProvider" name="ContentProvider" policy="dynamic" />
+   <service>
+      <provide interface="org.argeo.api.acr.ContentRepository"/>
+      <provide interface="org.argeo.api.acr.spi.ProvidedRepository"/>
+   </service>
+   <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
+   <reference bind="setUuidFactory" cardinality="1..1" interface="org.argeo.api.uuid.UuidFactory" name="UuidFactory" policy="static"/>
+   <reference bind="setUserManager" cardinality="1..1" interface="org.argeo.cms.CmsUserManager" name="CmsUserManager" policy="static"/>
+</scr:component>
index 102ae2adc0886dcbcfd7bb27f95e965cc504b00c..b00bc82f34be609199432beff19fc254ffea83fb 100644 (file)
@@ -2,8 +2,8 @@
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="true" name="CMS Deployment">
    <implementation class="org.argeo.cms.internal.runtime.CmsDeploymentImpl"/>
    <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
-   <reference bind="setHttpServer" cardinality="1..1" interface="com.sun.net.httpserver.HttpServer" policy="static"/>
-   <reference bind="addHttpHandler" unbind="removeHttpHandlerler" cardinality="0..1" interface="com.sun.net.httpserver.HttpHandler" policy="dynamic"/>
+   <reference bind="setHttpServer" cardinality="0..1" interface="com.sun.net.httpserver.HttpServer" policy="static"/>
+   <reference bind="addHttpHandler" unbind="removeHttpHandler" cardinality="0..1" interface="com.sun.net.httpserver.HttpHandler" policy="dynamic"/>
    <service>
       <provide interface="org.argeo.api.cms.CmsDeployment"/>
    </service>
diff --git a/org.argeo.cms/OSGI-INF/cmsOsgiLogger.xml b/org.argeo.cms/OSGI-INF/cmsOsgiLogger.xml
new file mode 100644 (file)
index 0000000..93fc5c0
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="true" name="CMS OSGi Logger">
+   <implementation class="org.argeo.cms.internal.osgi.CmsOsgiLogger"/>
+   <reference bind="setLogReaderService" cardinality="1..1" interface="org.osgi.service.log.LogReaderService" name="LogReaderService" policy="static"/>
+</scr:component>
diff --git a/org.argeo.cms/OSGI-INF/cmsUserAdmin.xml b/org.argeo.cms/OSGI-INF/cmsUserAdmin.xml
new file mode 100644 (file)
index 0000000..50a9ea6
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="Node User Admin">
+   <implementation class="org.argeo.cms.internal.runtime.CmsUserAdmin"/>
+   <property name="service.pid" type="String" value="org.argeo.api.userAdmin"/>
+   <reference bind="setTransactionManager" cardinality="1..1" interface="org.argeo.util.transaction.WorkControl" name="WorkControl" policy="static"/>
+   <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.util.transaction.WorkTransaction" name="WorkTransaction" policy="static"/>
+ <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
+ <service>
+    <provide interface="org.osgi.service.useradmin.UserAdmin"/>
+ </service>
+</scr:component>
diff --git a/org.argeo.cms/OSGI-INF/deployConfig.xml b/org.argeo.cms/OSGI-INF/deployConfig.xml
deleted file mode 100644 (file)
index 55755a9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="Deploy Config">
-   <implementation class="org.argeo.cms.internal.osgi.DeployConfig"/>
-   <service>
-      <provide interface="org.argeo.cms.internal.osgi.DeployConfig"/>
-   </service>
-   <reference bind="setConfigurationAdmin" cardinality="1..1" interface="org.osgi.service.cm.ConfigurationAdmin" name="ConfigurationAdmin" policy="static"/>
-   <reference cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
-</scr:component>
diff --git a/org.argeo.cms/OSGI-INF/nodeUserAdmin.xml b/org.argeo.cms/OSGI-INF/nodeUserAdmin.xml
deleted file mode 100644 (file)
index 50a9ea6..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="false" name="Node User Admin">
-   <implementation class="org.argeo.cms.internal.runtime.CmsUserAdmin"/>
-   <property name="service.pid" type="String" value="org.argeo.api.userAdmin"/>
-   <reference bind="setTransactionManager" cardinality="1..1" interface="org.argeo.util.transaction.WorkControl" name="WorkControl" policy="static"/>
-   <reference bind="setUserTransaction" cardinality="1..1" interface="org.argeo.util.transaction.WorkTransaction" name="WorkTransaction" policy="static"/>
- <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
- <service>
-    <provide interface="org.osgi.service.useradmin.UserAdmin"/>
- </service>
-</scr:component>
diff --git a/org.argeo.cms/OSGI-INF/simpleTransactionManager.xml b/org.argeo.cms/OSGI-INF/simpleTransactionManager.xml
deleted file mode 100644 (file)
index 8199747..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Simple Transaction Manager">
-   <implementation class="org.argeo.util.transaction.SimpleTransactionManager"/>
-   <service>
-      <provide interface="org.argeo.util.transaction.WorkControl"/>
-      <provide interface="org.argeo.util.transaction.WorkTransaction"/>
-   </service>
-</scr:component>
diff --git a/org.argeo.cms/OSGI-INF/transactionManager.xml b/org.argeo.cms/OSGI-INF/transactionManager.xml
new file mode 100644 (file)
index 0000000..8199747
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Simple Transaction Manager">
+   <implementation class="org.argeo.util.transaction.SimpleTransactionManager"/>
+   <service>
+      <provide interface="org.argeo.util.transaction.WorkControl"/>
+      <provide interface="org.argeo.util.transaction.WorkTransaction"/>
+   </service>
+</scr:component>
index bb8ed76bf9f87b2f3c829f578e3a98f36caae40b..bddc21f27467e144475a0dfdf223d3c8da7d0ccb 100644 (file)
@@ -7,13 +7,14 @@ org.apache.xerces.jaxp;resolution:=optional,\
 *
 
 Service-Component:\
+OSGI-INF/cmsOsgiLogger.xml,\
 OSGI-INF/cmsState.xml,\
-OSGI-INF/simpleTransactionManager.xml,\
-OSGI-INF/nodeUserAdmin.xml,\
+OSGI-INF/uuidFactory.xml,\
+OSGI-INF/transactionManager.xml,\
+OSGI-INF/cmsUserAdmin.xml,\
 OSGI-INF/cmsUserManager.xml,\
 OSGI-INF/cmsAuthenticator.xml,\
-OSGI-INF/uuidFactory.xml,\
-OSGI-INF/acrContentRepository.xml,\
+OSGI-INF/cmsContentRepository.xml,\
 OSGI-INF/cmsAcrHttpHandler.xml,\
 OSGI-INF/cmsDeployment.xml,\
 OSGI-INF/cmsContext.xml,\
index 11ab9e06e1ae5380241cd333f31c9c122472433f..960230a18734015c3458b908a7261a64e8d14290 100644 (file)
@@ -1,8 +1,6 @@
-output.. = bin/
 bin.includes = META-INF/,\
                .,\
                bin/,\
-               OSGI-INF/,\
-               OSGI-INF/cmsAuthenticator.xml,\
-               OSGI-INF/cmsAcrHttpHandler.xml
+               OSGI-INF/
 source.. = src/
+output.. = bin/
diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java
deleted file mode 100644 (file)
index a01858a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.argeo.cms;
-
-/** Framework agnostic interface for log notifications */
-@Deprecated
-public interface ArgeoLogListener {
-       /**
-        * Appends a log
-        * 
-        * @param username
-        *            authentified user, null for anonymous
-        * @param level
-        *            INFO, DEBUG, WARN, etc. (logging framework specific)
-        * @param category
-        *            hierarchy (logging framework specific)
-        * @param thread
-        *            name of the thread which logged this message
-        * @param msg
-        *            any object as long as its toString() method returns the
-        *            message
-        * @param exception
-        *            exception in log4j ThrowableStrRep format
-        */
-       public void appendLog(String username, Long timestamp, String level,
-                       String category, String thread, Object msg, String[] exception);
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java
deleted file mode 100644 (file)
index 71c5039..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.argeo.cms;
-
-/**
- * Logging framework agnostic identifying a logging service, to which one can
- * register
- */
-@Deprecated
-public interface ArgeoLogger {
-       /**
-        * Register for events by threads with the same authentication (or all
-        * threads if admin)
-        */
-       public void register(ArgeoLogListener listener,
-                       Integer numberOfPreviousEvents);
-
-       /**
-        * For admin use only: register for all users
-        * 
-        * @param listener
-        *            the log listener
-        * @param numberOfPreviousEvents
-        *            the number of previous events to notify
-        * @param everything
-        *            if true even anonymous is logged
-        */
-       public void registerForAll(ArgeoLogListener listener,
-                       Integer numberOfPreviousEvents, boolean everything);
-
-       public void unregister(ArgeoLogListener listener);
-
-       public void unregisterForAll(ArgeoLogListener listener);
-}
index d4b2f4595a8b400b0cadf5c8383c80614b0a1dcb..5e047d38a6b06db35900bd5439533e164646ff96 100644 (file)
@@ -4,7 +4,6 @@ import java.security.AllPermission;
 import java.util.Dictionary;
 
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.ArgeoLogger;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -13,7 +12,6 @@ import org.osgi.service.condpermadmin.ConditionInfo;
 import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
 import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
 import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
-import org.osgi.service.log.LogReaderService;
 import org.osgi.service.permissionadmin.PermissionInfo;
 
 /**
@@ -23,36 +21,22 @@ import org.osgi.service.permissionadmin.PermissionInfo;
 public class CmsActivator implements BundleActivator {
        private final static CmsLog log = CmsLog.getLog(CmsActivator.class);
 
-//     private static Activator instance;
-
        // TODO make it configurable
        private boolean hardened = false;
 
        private static BundleContext bundleContext;
 
-       private LogReaderService logReaderService;
-
-       private CmsOsgiLogger logger;
-//     private CmsStateImpl nodeState;
-//     private CmsDeploymentImpl nodeDeployment;
-//     private CmsContextImpl nodeInstance;
-
-//     private ServiceTracker<UserAdmin, NodeUserAdmin> userAdminSt;
-
-//     static {
-//             Bundle bundle = FrameworkUtil.getBundle(Activator.class);
-//             if (bundle != null) {
-//                     bundleContext = bundle.getBundleContext();
-//             }
-//     }
+//     private LogReaderService logReaderService;
+//
+//     private CmsOsgiLogger logger;
 
        void init() {
 //             Runtime.getRuntime().addShutdownHook(new CmsShutdown());
 //             instance = this;
 //             this.bc = bundleContext;
-               if (bundleContext != null)
-                       this.logReaderService = getService(LogReaderService.class);
-               initArgeoLogger();
+//             if (bundleContext != null)
+//                     this.logReaderService = getService(LogReaderService.class);
+//             initArgeoLogger();
 //             this.internalExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
 //
 //             try {
@@ -69,21 +53,8 @@ public class CmsActivator implements BundleActivator {
 
        void destroy() {
                try {
-//                     if (nodeInstance != null)
-//                             nodeInstance.shutdown();
-//                     if (nodeDeployment != null)
-//                             nodeDeployment.shutdown();
-//                     if (nodeState != null)
-//                             nodeState.shutdown();
-//
-//                     if (userAdminSt != null)
-//                             userAdminSt.close();
-
-//                     internalExecutorService.shutdown();
-//                     instance = null;
                        bundleContext = null;
-                       this.logReaderService = null;
-                       // this.configurationAdmin = null;
+//                     this.logReaderService = null;
                } catch (Exception e) {
                        log.error("CMS activator shutdown failed", e);
                }
@@ -127,26 +98,13 @@ public class CmsActivator implements BundleActivator {
 
        }
 
-       private void initArgeoLogger() {
-               logger = new CmsOsgiLogger(logReaderService);
-               if (bundleContext != null)
-                       bundleContext.registerService(ArgeoLogger.class, logger, null);
-       }
-
-//     private void initNode() throws IOException {
-//             // Node state
-//             nodeState = new CmsStateImpl();
-//             registerService(CmsState.class, nodeState, null);
-//
-//             // Node deployment
-//             nodeDeployment = new CmsDeploymentImpl();
-////           registerService(NodeDeployment.class, nodeDeployment, null);
-//
-//             // Node instance
-//             nodeInstance = new CmsContextImpl();
-//             registerService(CmsContext.class, nodeInstance, null);
+//     private void initArgeoLogger() {
+//             logger = new CmsOsgiLogger(logReaderService);
+//             if (bundleContext != null)
+//                     bundleContext.registerService(ArgeoLogger.class, logger, null);
 //     }
 
+
        public static <T> void registerService(Class<T> clss, T service, Dictionary<String, ?> properties) {
                if (bundleContext != null) {
                        bundleContext.registerService(clss, service, properties);
@@ -169,98 +127,18 @@ public class CmsActivator implements BundleActivator {
        @Override
        public void start(BundleContext bc) throws Exception {
                bundleContext = bc;
-//             if (!bc.getBundle().equals(bundleContext.getBundle()))
-//                     throw new IllegalStateException(
-//                                     "Bundle " + bc.getBundle() + " is not consistent with " + bundleContext.getBundle());
-               init();
-//             userAdminSt = new ServiceTracker<>(bundleContext, UserAdmin.class, null);
-//             userAdminSt.open();
 
-//             ServiceTracker<?, ?> httpSt = new ServiceTracker<HttpService, HttpService>(bc, HttpService.class, null) {
-//
-//                     @Override
-//                     public HttpService addingService(ServiceReference<HttpService> sr) {
-//                             Object httpPort = sr.getProperty("http.port");
-//                             Object httpsPort = sr.getProperty("https.port");
-//                             log.info(httpPortsMsg(httpPort, httpsPort));
-//                             close();
-//                             return super.addingService(sr);
-//                     }
-//             };
-//             httpSt.open();
-       }
+               init();
 
-       private String httpPortsMsg(Object httpPort, Object httpsPort) {
-               return (httpPort != null ? "HTTP " + httpPort + " " : " ") + (httpsPort != null ? "HTTPS " + httpsPort : "");
        }
 
        @Override
        public void stop(BundleContext bc) throws Exception {
-//             if (!bc.getBundle().equals(bundleContext.getBundle()))
-//                     throw new IllegalStateException(
-//                                     "Bundle " + bc.getBundle() + " is not consistent with " + bundleContext.getBundle());
+
                destroy();
                bundleContext = null;
        }
 
-//     private <T> T getService(Class<T> clazz) {
-//             ServiceReference<T> sr = bundleContext.getServiceReference(clazz);
-//             if (sr == null)
-//                     throw new IllegalStateException("No service available for " + clazz);
-//             return bundleContext.getService(sr);
-//     }
-
-//     public static GSSCredential getAcceptorCredentials() {
-//             return getNodeUserAdmin().getAcceptorCredentials();
-//     }
-//
-//     @Deprecated
-//     public static boolean isSingleUser() {
-//             return getNodeUserAdmin().isSingleUser();
-//     }
-//
-//     public static UserAdmin getUserAdmin() {
-//             return (UserAdmin) getNodeUserAdmin();
-//     }
-//
-//     public static String getHttpProxySslHeader() {
-//             return KernelUtils.getFrameworkProp(CmsConstants.HTTP_PROXY_SSL_DN);
-//     }
-//
-//     private static NodeUserAdmin getNodeUserAdmin() {
-//             NodeUserAdmin res;
-//             try {
-//                     res = instance.userAdminSt.waitForService(60000);
-//             } catch (InterruptedException e) {
-//                     throw new IllegalStateException("Cannot retrieve Node user admin", e);
-//             }
-//             if (res == null)
-//                     throw new IllegalStateException("No Node user admin found");
-//
-//             return res;
-//             // ServiceReference<UserAdmin> sr =
-//             // instance.bc.getServiceReference(UserAdmin.class);
-//             // NodeUserAdmin userAdmin = (NodeUserAdmin) instance.bc.getService(sr);
-//             // return userAdmin;
-//
-//     }
-
-//     public static ExecutorService getInternalExecutorService() {
-//             return instance.internalExecutorService;
-//     }
-
-       // static CmsSecurity getCmsSecurity() {
-       // return instance.nodeSecurity;
-       // }
-
-//     public String[] getLocales() {
-//             // TODO optimize?
-//             List<Locale> locales = CmsStateImpl.getNodeState().getLocales();
-//             String[] res = new String[locales.size()];
-//             for (int i = 0; i < locales.size(); i++)
-//                     res[i] = locales.get(i).toString();
-//             return res;
-//     }
 
        public static BundleContext getBundleContext() {
                return bundleContext;
index 2936df28a52af1c9c0091ad058dd065bef3a51e0..3358ed82574eb53562c955f6a9111ebf82c74aff 100644 (file)
@@ -1,31 +1,10 @@
 package org.argeo.cms.internal.osgi;
 
-import java.io.IOException;
-import java.nio.file.FileSystems;
-import java.nio.file.Path;
-import java.nio.file.StandardWatchEventKinds;
-import java.nio.file.WatchEvent;
-import java.nio.file.WatchKey;
-import java.nio.file.WatchService;
 import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.ArgeoLogListener;
-import org.argeo.cms.ArgeoLogger;
-import org.argeo.cms.auth.CurrentUser;
 import org.argeo.util.directory.DirectoryConf;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
@@ -36,51 +15,49 @@ import org.osgi.service.log.LogLevel;
 import org.osgi.service.log.LogListener;
 import org.osgi.service.log.LogReaderService;
 
-/** Not meant to be used directly in standard log4j config */
-public class CmsOsgiLogger implements ArgeoLogger, LogListener {
+/** Logs OSGi events. */
+public class CmsOsgiLogger implements LogListener {
        private final static String WHITEBOARD_PATTERN_PROP = "osgi.http.whiteboard.servlet.pattern";
        private final static String CONTEXT_NAME_PROP = "contextName";
+       
+       private LogReaderService logReaderService;
 
-       /** Internal debug for development purposes. */
-       private static Boolean debug = false;
+//     /** Internal debug for development purposes. */
+//     private static Boolean debug = false;
 
-       private Boolean disabled = false;
-
-       private String level = null;
+//     private Boolean disabled = false;
+//
+//     private String level = null;
 
 //     private Level log4jLevel = null;
 
-       private Properties configuration;
-
-       private AppenderImpl appender;
+//     private Properties configuration;
 
-       private final List<ArgeoLogListener> everythingListeners = Collections
-                       .synchronizedList(new ArrayList<ArgeoLogListener>());
-       private final List<ArgeoLogListener> allUsersListeners = Collections
-                       .synchronizedList(new ArrayList<ArgeoLogListener>());
-       private final Map<String, List<ArgeoLogListener>> userListeners = Collections
-                       .synchronizedMap(new HashMap<String, List<ArgeoLogListener>>());
+//     private AppenderImpl appender;
 
-       private BlockingQueue<LogEvent> events;
-       private LogDispatcherThread logDispatcherThread = new LogDispatcherThread();
+//     private BlockingQueue<LogEvent> events;
+//     private LogDispatcherThread logDispatcherThread = new LogDispatcherThread();
 
-       private Integer maxLastEventsCount = 10 * 1000;
-
-       /** Marker to prevent stack overflow */
-       private ThreadLocal<Boolean> dispatching = new ThreadLocal<Boolean>() {
+//     private Integer maxLastEventsCount = 10 * 1000;
+//
+//     /** Marker to prevent stack overflow */
+//     private ThreadLocal<Boolean> dispatching = new ThreadLocal<Boolean>() {
+//
+//             @Override
+//             protected Boolean initialValue() {
+//                     return false;
+//             }
+//     };
 
-               @Override
-               protected Boolean initialValue() {
-                       return false;
-               }
-       };
+//     public CmsOsgiLogger(LogReaderService lrs) {
+//     }
 
-       public CmsOsgiLogger(LogReaderService lrs) {
-               if (lrs != null) {
-                       Enumeration<LogEntry> logEntries = lrs.getLog();
+       public void start() {
+               if (logReaderService != null) {
+                       Enumeration<LogEntry> logEntries = logReaderService.getLog();
                        while (logEntries.hasMoreElements())
                                logged(logEntries.nextElement());
-                       lrs.addLogListener(this);
+                       logReaderService.addLogListener(this);
 
                        // configure log4j watcher
 //                     String log4jConfiguration = KernelUtils.getFrameworkProp("log4j.configuration");
@@ -104,43 +81,31 @@ public class CmsOsgiLogger implements ArgeoLogger, LogListener {
 //                             }
 //                     }
                }
+//             try {
+////                   events = new LinkedBlockingQueue<LogEvent>();
+////
+////                   // if (layout != null)
+////                   // setLayout(layout);
+////                   // else
+////                   // setLayout(new PatternLayout(pattern));
+//////                 appender = new AppenderImpl();
+////                   reloadConfiguration();
+//////                 Logger.getRootLogger().addAppender(appender);
+////
+////                   logDispatcherThread = new LogDispatcherThread();
+////                   logDispatcherThread.start();
+//             } catch (Exception e) {
+//                     throw new IllegalStateException("Cannot initialize log4j");
+//             }
        }
 
-       public void init() {
-               try {
-                       events = new LinkedBlockingQueue<LogEvent>();
-
-                       // if (layout != null)
-                       // setLayout(layout);
-                       // else
-                       // setLayout(new PatternLayout(pattern));
-                       appender = new AppenderImpl();
-                       reloadConfiguration();
-//                     Logger.getRootLogger().addAppender(appender);
-
-                       logDispatcherThread = new LogDispatcherThread();
-                       logDispatcherThread.start();
-               } catch (Exception e) {
-                       throw new IllegalStateException("Cannot initialize log4j");
-               }
-       }
-
-       public void destroy() throws Exception {
-//             Logger.getRootLogger().removeAppender(appender);
-               allUsersListeners.clear();
-               for (List<ArgeoLogListener> lst : userListeners.values())
-                       lst.clear();
-               userListeners.clear();
-
-               events.clear();
-               events = null;
-               logDispatcherThread.interrupt();
+       public void stop() throws Exception {
+//             events.clear();
+//             events = null;
+//             logDispatcherThread.interrupt();
+               logReaderService.removeLogListener(this);
        }
 
-       // public void setLayout(Layout layout) {
-       // this.layout = layout;
-       // }
-
        public String toString() {
                return "Node Logger";
        }
@@ -247,295 +212,300 @@ public class CmsOsgiLogger implements ArgeoLogger, LogListener {
                return false;
        }
 
+       public void setLogReaderService(LogReaderService logReaderService) {
+               this.logReaderService = logReaderService;
+       }
+
+       
        //
        // ARGEO LOGGER
        //
 
-       public synchronized void register(ArgeoLogListener listener, Integer numberOfPreviousEvents) {
-               String username = CurrentUser.getUsername();
-               if (username == null)
-                       throw new IllegalStateException("Only authenticated users can register a log listener");
-
-               if (!userListeners.containsKey(username)) {
-                       List<ArgeoLogListener> lst = Collections.synchronizedList(new ArrayList<ArgeoLogListener>());
-                       userListeners.put(username, lst);
-               }
-               userListeners.get(username).add(listener);
-               List<LogEvent> lastEvents = logDispatcherThread.getLastEvents(username, numberOfPreviousEvents);
-               for (LogEvent evt : lastEvents)
-                       dispatchEvent(listener, evt);
-       }
-
-       public synchronized void registerForAll(ArgeoLogListener listener, Integer numberOfPreviousEvents,
-                       boolean everything) {
-               if (everything)
-                       everythingListeners.add(listener);
-               else
-                       allUsersListeners.add(listener);
-               List<LogEvent> lastEvents = logDispatcherThread.getLastEvents(null, numberOfPreviousEvents);
-               for (LogEvent evt : lastEvents)
-                       if (everything || evt.getUsername() != null)
-                               dispatchEvent(listener, evt);
-       }
-
-       public synchronized void unregister(ArgeoLogListener listener) {
-               String username = CurrentUser.getUsername();
-               if (username == null)// FIXME
-                       return;
-               if (!userListeners.containsKey(username))
-                       throw new IllegalStateException("No user listeners " + listener + " registered for user " + username);
-               if (!userListeners.get(username).contains(listener))
-                       throw new IllegalStateException("No user listeners " + listener + " registered for user " + username);
-               userListeners.get(username).remove(listener);
-               if (userListeners.get(username).isEmpty())
-                       userListeners.remove(username);
-
-       }
-
-       public synchronized void unregisterForAll(ArgeoLogListener listener) {
-               everythingListeners.remove(listener);
-               allUsersListeners.remove(listener);
-       }
-
-       /** For development purpose, since using regular logging is not easy here */
-       private static void stdOut(Object obj) {
-               System.out.println(obj);
-       }
-
-       private static void stdErr(Object obj) {
-               System.err.println(obj);
-       }
-
-       private static void debug(Object obj) {
-               if (debug)
-                       System.out.println(obj);
-       }
-
-       private static boolean isInternalDebugEnabled() {
-               return debug;
-       }
+//     public synchronized void register(ArgeoLogListener listener, Integer numberOfPreviousEvents) {
+//             String username = CurrentUser.getUsername();
+//             if (username == null)
+//                     throw new IllegalStateException("Only authenticated users can register a log listener");
+//
+//             if (!userListeners.containsKey(username)) {
+//                     List<ArgeoLogListener> lst = Collections.synchronizedList(new ArrayList<ArgeoLogListener>());
+//                     userListeners.put(username, lst);
+//             }
+//             userListeners.get(username).add(listener);
+//             List<LogEvent> lastEvents = logDispatcherThread.getLastEvents(username, numberOfPreviousEvents);
+//             for (LogEvent evt : lastEvents)
+//                     dispatchEvent(listener, evt);
+//     }
+//
+//     public synchronized void registerForAll(ArgeoLogListener listener, Integer numberOfPreviousEvents,
+//                     boolean everything) {
+//             if (everything)
+//                     everythingListeners.add(listener);
+//             else
+//                     allUsersListeners.add(listener);
+//             List<LogEvent> lastEvents = logDispatcherThread.getLastEvents(null, numberOfPreviousEvents);
+//             for (LogEvent evt : lastEvents)
+//                     if (everything || evt.getUsername() != null)
+//                             dispatchEvent(listener, evt);
+//     }
+//
+//     public synchronized void unregister(ArgeoLogListener listener) {
+//             String username = CurrentUser.getUsername();
+//             if (username == null)// FIXME
+//                     return;
+//             if (!userListeners.containsKey(username))
+//                     throw new IllegalStateException("No user listeners " + listener + " registered for user " + username);
+//             if (!userListeners.get(username).contains(listener))
+//                     throw new IllegalStateException("No user listeners " + listener + " registered for user " + username);
+//             userListeners.get(username).remove(listener);
+//             if (userListeners.get(username).isEmpty())
+//                     userListeners.remove(username);
+//
+//     }
+//
+//     public synchronized void unregisterForAll(ArgeoLogListener listener) {
+//             everythingListeners.remove(listener);
+//             allUsersListeners.remove(listener);
+//     }
+
+//     /** For development purpose, since using regular logging is not easy here */
+//     private static void stdOut(Object obj) {
+//             System.out.println(obj);
+//     }
+//
+//     private static void stdErr(Object obj) {
+//             System.err.println(obj);
+//     }
+//
+//     private static void debug(Object obj) {
+//             if (debug)
+//                     System.out.println(obj);
+//     }
+//
+//     private static boolean isInternalDebugEnabled() {
+//             return debug;
+//     }
 
        // public void setPattern(String pattern) {
        // this.pattern = pattern;
        // }
 
-       public void setDisabled(Boolean disabled) {
-               this.disabled = disabled;
-       }
-
-       public void setLevel(String level) {
-               this.level = level;
-       }
-
-       public void setConfiguration(Properties configuration) {
-               this.configuration = configuration;
-       }
-
-       public void updateConfiguration(Properties configuration) {
-               setConfiguration(configuration);
-               reloadConfiguration();
-       }
-
-       public Properties getConfiguration() {
-               return configuration;
-       }
-
-       /**
-        * Reloads configuration (if the configuration {@link Properties} is set)
-        */
-       protected void reloadConfiguration() {
-               if (configuration != null) {
-//                     LogManager.resetConfiguration();
-//                     PropertyConfigurator.configure(configuration);
-               }
-       }
-
-       protected synchronized void processLoggingEvent(LogEvent event) {
-               if (disabled)
-                       return;
-
-               if (dispatching.get())
-                       return;
-
-               if (level != null && !level.trim().equals("")) {
-//                     if (log4jLevel == null || !log4jLevel.toString().equals(level))
-//                             try {
-//                                     log4jLevel = Level.toLevel(level);
-//                             } catch (Exception e) {
-//                                     System.err.println("Log4j level could not be set for level '" + level + "', resetting it to null.");
-//                                     e.printStackTrace();
-//                                     level = null;
-//                             }
+//     public void setDisabled(Boolean disabled) {
+//             this.disabled = disabled;
+//     }
 //
-//                     if (log4jLevel != null && !event.getLoggingEvent().getLevel().isGreaterOrEqual(log4jLevel)) {
-//                             return;
-//                     }
-               }
-
-               try {
-                       // admin listeners
-                       Iterator<ArgeoLogListener> everythingIt = everythingListeners.iterator();
-                       while (everythingIt.hasNext())
-                               dispatchEvent(everythingIt.next(), event);
-
-                       if (event.getUsername() != null) {
-                               Iterator<ArgeoLogListener> allUsersIt = allUsersListeners.iterator();
-                               while (allUsersIt.hasNext())
-                                       dispatchEvent(allUsersIt.next(), event);
-
-                               if (userListeners.containsKey(event.getUsername())) {
-                                       Iterator<ArgeoLogListener> userIt = userListeners.get(event.getUsername()).iterator();
-                                       while (userIt.hasNext())
-                                               dispatchEvent(userIt.next(), event);
-                               }
-                       }
-               } catch (Exception e) {
-                       stdOut("Cannot process logging event");
-                       e.printStackTrace();
-               }
-       }
-
-       protected void dispatchEvent(ArgeoLogListener logListener, LogEvent evt) {
-//             LoggingEvent event = evt.getLoggingEvent();
-//             logListener.appendLog(evt.getUsername(), event.getTimeStamp(), event.getLevel().toString(),
-//                             event.getLoggerName(), event.getThreadName(), event.getMessage(), event.getThrowableStrRep());
-       }
+//     public void setLevel(String level) {
+//             this.level = level;
+//     }
 
-       private class AppenderImpl { // extends AppenderSkeleton {
-               public boolean requiresLayout() {
-                       return false;
-               }
+//     public void setConfiguration(Properties configuration) {
+//             this.configuration = configuration;
+//     }
+//
+//     public void updateConfiguration(Properties configuration) {
+//             setConfiguration(configuration);
+//             reloadConfiguration();
+//     }
+//
+//     public Properties getConfiguration() {
+//             return configuration;
+//     }
+//
+//     /**
+//      * Reloads configuration (if the configuration {@link Properties} is set)
+//      */
+//     protected void reloadConfiguration() {
+//             if (configuration != null) {
+////                   LogManager.resetConfiguration();
+////                   PropertyConfigurator.configure(configuration);
+//             }
+//     }
 
-               public void close() {
-               }
+//     protected synchronized void processLoggingEvent(LogEvent event) {
+//             if (disabled)
+//                     return;
+//
+//             if (dispatching.get())
+//                     return;
+//
+//             if (level != null && !level.trim().equals("")) {
+////                   if (log4jLevel == null || !log4jLevel.toString().equals(level))
+////                           try {
+////                                   log4jLevel = Level.toLevel(level);
+////                           } catch (Exception e) {
+////                                   System.err.println("Log4j level could not be set for level '" + level + "', resetting it to null.");
+////                                   e.printStackTrace();
+////                                   level = null;
+////                           }
+////
+////                   if (log4jLevel != null && !event.getLoggingEvent().getLevel().isGreaterOrEqual(log4jLevel)) {
+////                           return;
+////                   }
+//             }
+//
+////           try {
+////                   // admin listeners
+////                   Iterator<ArgeoLogListener> everythingIt = everythingListeners.iterator();
+////                   while (everythingIt.hasNext())
+////                           dispatchEvent(everythingIt.next(), event);
+////
+////                   if (event.getUsername() != null) {
+////                           Iterator<ArgeoLogListener> allUsersIt = allUsersListeners.iterator();
+////                           while (allUsersIt.hasNext())
+////                                   dispatchEvent(allUsersIt.next(), event);
+////
+////                           if (userListeners.containsKey(event.getUsername())) {
+////                                   Iterator<ArgeoLogListener> userIt = userListeners.get(event.getUsername()).iterator();
+////                                   while (userIt.hasNext())
+////                                           dispatchEvent(userIt.next(), event);
+////                           }
+////                   }
+////           } catch (Exception e) {
+////                   stdOut("Cannot process logging event");
+////                   e.printStackTrace();
+////           }
+//     }
+
+//     protected void dispatchEvent(ArgeoLogListener logListener, LogEvent evt) {
+////           LoggingEvent event = evt.getLoggingEvent();
+////           logListener.appendLog(evt.getUsername(), event.getTimeStamp(), event.getLevel().toString(),
+////                           event.getLoggerName(), event.getThreadName(), event.getMessage(), event.getThrowableStrRep());
+//     }
+
+//     private class AppenderImpl { // extends AppenderSkeleton {
+//             public boolean requiresLayout() {
+//                     return false;
+//             }
+//
+//             public void close() {
+//             }
+//
+////           @Override
+////           protected void append(LoggingEvent event) {
+////                   if (events != null) {
+////                           try {
+////                                   String username = CurrentUser.getUsername();
+////                                   events.put(new LogEvent(username, event));
+////                           } catch (InterruptedException e) {
+////                                   // silent
+////                           }
+////                   }
+////           }
+//
+//     }
 
-//             @Override
-//             protected void append(LoggingEvent event) {
-//                     if (events != null) {
+//     private class LogDispatcherThread extends Thread {
+//             /** encapsulated in order to simplify concurrency management */
+//             private LinkedList<LogEvent> lastEvents = new LinkedList<LogEvent>();
+//
+//             public LogDispatcherThread() {
+//                     super("Argeo Logging Dispatcher Thread");
+//             }
+//
+//             public void run() {
+//                     while (events != null) {
 //                             try {
-//                                     String username = CurrentUser.getUsername();
-//                                     events.put(new LogEvent(username, event));
+//                                     LogEvent loggingEvent = events.take();
+//                                     processLoggingEvent(loggingEvent);
+//                                     addLastEvent(loggingEvent);
 //                             } catch (InterruptedException e) {
-//                                     // silent
+//                                     if (events == null)
+//                                             return;
 //                             }
 //                     }
 //             }
+//
+//             protected synchronized void addLastEvent(LogEvent loggingEvent) {
+//                     if (lastEvents.size() >= maxLastEventsCount)
+//                             lastEvents.poll();
+//                     lastEvents.add(loggingEvent);
+//             }
+//
+//             public synchronized List<LogEvent> getLastEvents(String username, Integer maxCount) {
+//                     LinkedList<LogEvent> evts = new LinkedList<LogEvent>();
+//                     ListIterator<LogEvent> it = lastEvents.listIterator(lastEvents.size());
+//                     int count = 0;
+//                     while (it.hasPrevious() && (count < maxCount)) {
+//                             LogEvent evt = it.previous();
+//                             if (username == null || username.equals(evt.getUsername())) {
+//                                     evts.push(evt);
+//                                     count++;
+//                             }
+//                     }
+//                     return evts;
+//             }
+//     }
 
-       }
-
-       private class LogDispatcherThread extends Thread {
-               /** encapsulated in order to simplify concurrency management */
-               private LinkedList<LogEvent> lastEvents = new LinkedList<LogEvent>();
-
-               public LogDispatcherThread() {
-                       super("Argeo Logging Dispatcher Thread");
-               }
-
-               public void run() {
-                       while (events != null) {
-                               try {
-                                       LogEvent loggingEvent = events.take();
-                                       processLoggingEvent(loggingEvent);
-                                       addLastEvent(loggingEvent);
-                               } catch (InterruptedException e) {
-                                       if (events == null)
-                                               return;
-                               }
-                       }
-               }
-
-               protected synchronized void addLastEvent(LogEvent loggingEvent) {
-                       if (lastEvents.size() >= maxLastEventsCount)
-                               lastEvents.poll();
-                       lastEvents.add(loggingEvent);
-               }
-
-               public synchronized List<LogEvent> getLastEvents(String username, Integer maxCount) {
-                       LinkedList<LogEvent> evts = new LinkedList<LogEvent>();
-                       ListIterator<LogEvent> it = lastEvents.listIterator(lastEvents.size());
-                       int count = 0;
-                       while (it.hasPrevious() && (count < maxCount)) {
-                               LogEvent evt = it.previous();
-                               if (username == null || username.equals(evt.getUsername())) {
-                                       evts.push(evt);
-                                       count++;
-                               }
-                       }
-                       return evts;
-               }
-       }
-
-       private class LogEvent {
-               private final String username;
-//             private final LoggingEvent loggingEvent;
-
-               public LogEvent(String username) {
-                       super();
-                       this.username = username;
-//                     this.loggingEvent = loggingEvent;
-               }
-
-//             @Override
-//             public int hashCode() {
-//                     return loggingEvent.hashCode();
+//     private class LogEvent {
+//             private final String username;
+////           private final LoggingEvent loggingEvent;
+//
+//             public LogEvent(String username) {
+//                     super();
+//                     this.username = username;
+////                   this.loggingEvent = loggingEvent;
 //             }
 //
-//             @Override
-//             public boolean equals(Object obj) {
-//                     return loggingEvent.equals(obj);
+////           @Override
+////           public int hashCode() {
+////                   return loggingEvent.hashCode();
+////           }
+////
+////           @Override
+////           public boolean equals(Object obj) {
+////                   return loggingEvent.equals(obj);
+////           }
+////
+////           @Override
+////           public String toString() {
+////                   return username + "@ " + loggingEvent.toString();
+////           }
+//
+//             public String getUsername() {
+//                     return username;
 //             }
 //
-//             @Override
-//             public String toString() {
-//                     return username + "@ " + loggingEvent.toString();
+////           public LoggingEvent getLoggingEvent() {
+////                   return loggingEvent;
+////           }
+//
+//     }
+//
+//     private class Log4jConfWatcherThread extends Thread {
+//             private Path log4jConfigurationPath;
+//
+//             public Log4jConfWatcherThread(Path log4jConfigurationPath) {
+//                     super("Log4j Configuration Watcher");
+//                     try {
+//                             this.log4jConfigurationPath = log4jConfigurationPath.toRealPath();
+//                     } catch (IOException e) {
+//                             this.log4jConfigurationPath = log4jConfigurationPath.toAbsolutePath();
+//                             stdOut("Cannot determine real path for " + log4jConfigurationPath + ": " + e.getMessage());
+//                     }
 //             }
-
-               public String getUsername() {
-                       return username;
-               }
-
-//             public LoggingEvent getLoggingEvent() {
-//                     return loggingEvent;
+//
+//             public void run() {
+//                     Path parentDir = log4jConfigurationPath.getParent();
+//                     try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
+//                             parentDir.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
+//                             WatchKey wk;
+//                             watching: while ((wk = watchService.take()) != null) {
+//                                     for (WatchEvent<?> event : wk.pollEvents()) {
+//                                             final Path changed = (Path) event.context();
+//                                             if (log4jConfigurationPath.equals(parentDir.resolve(changed))) {
+//                                                     if (isInternalDebugEnabled())
+//                                                             debug(log4jConfigurationPath + " has changed, reloading.");
+////                                                   PropertyConfigurator.configure(log4jConfigurationPath.toUri().toURL());
+//                                             }
+//                                     }
+//                                     // reset the key
+//                                     boolean valid = wk.reset();
+//                                     if (!valid) {
+//                                             break watching;
+//                                     }
+//                             }
+//                     } catch (IOException | InterruptedException e) {
+//                             stdErr("Log4j configuration watcher failed: " + e.getMessage());
+//                     }
 //             }
-
-       }
-
-       private class Log4jConfWatcherThread extends Thread {
-               private Path log4jConfigurationPath;
-
-               public Log4jConfWatcherThread(Path log4jConfigurationPath) {
-                       super("Log4j Configuration Watcher");
-                       try {
-                               this.log4jConfigurationPath = log4jConfigurationPath.toRealPath();
-                       } catch (IOException e) {
-                               this.log4jConfigurationPath = log4jConfigurationPath.toAbsolutePath();
-                               stdOut("Cannot determine real path for " + log4jConfigurationPath + ": " + e.getMessage());
-                       }
-               }
-
-               public void run() {
-                       Path parentDir = log4jConfigurationPath.getParent();
-                       try (final WatchService watchService = FileSystems.getDefault().newWatchService()) {
-                               parentDir.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
-                               WatchKey wk;
-                               watching: while ((wk = watchService.take()) != null) {
-                                       for (WatchEvent<?> event : wk.pollEvents()) {
-                                               final Path changed = (Path) event.context();
-                                               if (log4jConfigurationPath.equals(parentDir.resolve(changed))) {
-                                                       if (isInternalDebugEnabled())
-                                                               debug(log4jConfigurationPath + " has changed, reloading.");
-//                                                     PropertyConfigurator.configure(log4jConfigurationPath.toUri().toURL());
-                                               }
-                                       }
-                                       // reset the key
-                                       boolean valid = wk.reset();
-                                       if (!valid) {
-                                               break watching;
-                                       }
-                               }
-                       } catch (IOException | InterruptedException e) {
-                               stdErr("Log4j configuration watcher failed: " + e.getMessage());
-                       }
-               }
-       }
+//     }
 }
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java b/org.argeo.cms/src/org/argeo/cms/internal/osgi/DeployConfig.java
deleted file mode 100644 (file)
index 7f8db5a..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-package org.argeo.cms.internal.osgi;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Writer;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import javax.naming.InvalidNameException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttributes;
-import javax.naming.ldap.LdapName;
-import javax.naming.ldap.Rdn;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.util.directory.DirectoryConf;
-import org.argeo.util.directory.ldap.AttributesDictionary;
-import org.argeo.util.directory.ldap.LdifParser;
-import org.argeo.util.directory.ldap.LdifWriter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ConfigurationEvent;
-
-/** Manages the LDIF-based deployment configuration. */
-@Deprecated
-public class DeployConfig {
-
-       private final CmsLog log = CmsLog.getLog(getClass());
-//     private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
-
-       private static Path deployConfigPath;// = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH);
-       private SortedMap<LdapName, Attributes> deployConfigs = new TreeMap<>();
-//     private final DataModels dataModels;
-
-       private boolean isFirstInit = false;
-
-       private final static String ROLES = "roles";
-
-       private ConfigurationAdmin configurationAdmin;
-
-       private void firstInit() throws IOException {
-               log.info("## FIRST INIT ##");
-               Files.createDirectories(deployConfigPath.getParent());
-
-               // FirstInit firstInit = new FirstInit();
-               //InitUtils.prepareFirstInitInstanceArea();
-
-               if (!Files.exists(deployConfigPath))
-                       deployConfigs = new TreeMap<>();
-               else// config file could have juste been copied by preparation
-                       try (InputStream in = Files.newInputStream(deployConfigPath)) {
-                               deployConfigs = new LdifParser().read(in);
-                       }
-               save();
-       }
-
-       private void setFromFrameworkProperties(boolean isFirstInit) {
-
-               // user admin
-//             List<Dictionary<String, Object>> userDirectoryConfigs = InitUtils.getUserDirectoryConfigs();
-//             if (userDirectoryConfigs.size() != 0) {
-//                     List<String> activeCns = new ArrayList<>();
-//                     for (int i = 0; i < userDirectoryConfigs.size(); i++) {
-//                             Dictionary<String, Object> userDirectoryConfig = userDirectoryConfigs.get(i);
-//                             String baseDn = (String) userDirectoryConfig.get(DirectoryConf.baseDn.name());
-//                             String cn;
-//                             if (CmsConstants.ROLES_BASEDN.equals(baseDn))
-//                                     cn = ROLES;
-//                             else
-//                                     cn = DirectoryConf.baseDnHash(userDirectoryConfig);
-//                             activeCns.add(cn);
-//                             userDirectoryConfig.put(CmsConstants.CN, cn);
-//                             putFactoryDeployConfig(CmsConstants.NODE_USER_ADMIN_PID, userDirectoryConfig);
-//                     }
-//                     // disable others
-//                     LdapName userAdminFactoryName = serviceFactoryDn(CmsConstants.NODE_USER_ADMIN_PID);
-//                     for (LdapName name : deployConfigs.keySet()) {
-//                             if (name.startsWith(userAdminFactoryName) && !name.equals(userAdminFactoryName)) {
-////                                   try {
-//                                     Attributes attrs = deployConfigs.get(name);
-//                                     String cn = name.getRdn(name.size() - 1).getValue().toString();
-//                                     if (!activeCns.contains(cn)) {
-//                                             attrs.put(DirectoryConf.disabled.name(), "true");
-//                                     }
-////                                   } catch (Exception e) {
-////                                           throw new CmsException("Cannot disable user directory " + name, e);
-////                                   }
-//                             }
-//                     }
-//             }
-
-               // http server
-//             Dictionary<String, Object> webServerConfig = InitUtils
-//                             .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT));
-//             if (!webServerConfig.isEmpty()) {
-//                     // TODO check for other customizers
-//                     putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig);
-//             }
-
-               // SAVE
-               save();
-               //
-
-       }
-
-       public void start() {
-               try {
-                       if (!isInitialized()) { // first init
-                               isFirstInit = true;
-                               firstInit();
-                       }
-
-                       boolean isClean = true;
-                       if (configurationAdmin != null)
-                               try {
-                                       Configuration[] confs = configurationAdmin
-                                                       .listConfigurations("(service.factoryPid=" + CmsConstants.NODE_USER_ADMIN_PID + ")");
-                                       isClean = confs == null || confs.length == 0;
-                               } catch (Exception e) {
-                                       throw new IllegalStateException("Cannot analyse clean state", e);
-                               }
-
-                       try (InputStream in = Files.newInputStream(deployConfigPath)) {
-                               deployConfigs = new LdifParser().read(in);
-                       }
-                       if (isClean) {
-                               if (log.isDebugEnabled())
-                                       log.debug("Clean state, loading from framework properties...");
-                               setFromFrameworkProperties(isFirstInit);
-                               if (configurationAdmin != null)
-                                       loadConfigs();
-                       }
-                       // TODO check consistency if not clean
-               } catch (IOException e) {
-                       throw new RuntimeException("Cannot load deploy configuration", e);
-               }
-       }
-
-       public void stop() {
-
-       }
-
-       protected void logAllConfigurations() {
-               if (!log.isDebugEnabled())
-                       return;
-               try {
-                       Configuration[] configurations = configurationAdmin.listConfigurations(null);
-                       if (configurations == null) {
-                               log.debug("No configuration available");
-                               return;
-                       }
-                       Arrays.sort(configurations, (o1, o2) -> o1.getPid().compareTo(o2.getPid()));
-                       for (Configuration configuration : configurations) {
-                               log.debug(configuration.getFactoryPid() + " - " + configuration.getPid() + " - "
-                                               + configuration.getProperties());
-                       }
-               } catch (IOException | InvalidSyntaxException e) {
-                       throw new IllegalStateException("Cannot log configurations", e);
-               }
-       }
-
-       public void loadConfigs() throws IOException {
-               // FIXME make it more robust
-               Configuration systemRolesConf = null;
-               LdapName systemRolesDn;
-               try {
-                       // FIXME make it more robust
-                       systemRolesDn = new LdapName("cn=roles,ou=org.argeo.api.userAdmin,ou=deploy,ou=node");
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException(e);
-               }
-               deployConfigs: for (LdapName dn : deployConfigs.keySet()) {
-                       Attributes deployConfig = deployConfigs.get(dn);
-                       Rdn lastRdn = dn.getRdn(dn.size() - 1);
-                       LdapName prefix = (LdapName) dn.getPrefix(dn.size() - 1);
-                       if (prefix.toString().equals(CmsConstants.DEPLOY_BASEDN)) {
-                               if (lastRdn.getType().equals(CmsConstants.CN)) {
-                                       // service
-                                       String pid = lastRdn.getValue().toString();
-                                       Configuration conf = configurationAdmin.getConfiguration(pid);
-                                       AttributesDictionary dico = new AttributesDictionary(deployConfig);
-                                       conf.update(dico);
-                               } else {
-                                       // service factory definition
-                               }
-                       } else {
-                               Attribute disabled = deployConfig.get(DirectoryConf.disabled.name());
-                               if (disabled != null)
-                                       continue deployConfigs;
-                               // service factory service
-                               if (!lastRdn.getType().equals(CmsConstants.CN))
-                                       throw new IllegalStateException("Only " + CmsConstants.CN + "= is supported: " + dn);
-                               Rdn beforeLastRdn = dn.getRdn(dn.size() - 2);
-                               assert beforeLastRdn.getType().equals(CmsConstants.OU);
-                               String factoryPid = beforeLastRdn.getValue().toString();
-
-                               String cn = lastRdn.getValue().toString();
-                               Configuration conf = getSingleServiceConfiguration(factoryPid, cn);
-                               if (conf != null) {
-                                       if (systemRolesDn.equals(dn))
-                                               systemRolesConf = conf;
-                                       // TODO deal with modifications
-//                                     boolean modified = false;
-//                                     Dictionary<String, Object> currentProperties = conf.getProperties();
-//
-//                                     attrs: for (NamingEnumeration<? extends Attribute> it = deployConfig.getAll(); it
-//                                                     .hasMoreElements();) {
-//                                             Attribute attr = (Attribute) it.next();
-//                                             String key = attr.getID();
-//                                             Object currentValue = currentProperties.get(key);
-//                                             if (currentValue == null) {
-//                                                     modified = true;
-//                                                     break attrs;
-//                                             }
-//                                     }
-
-//                                     AttributesDictionary dico = new AttributesDictionary(deployConfig);
-//                                     conf.update(dico);
-                               } else {
-
-                                       conf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null);
-                                       if (systemRolesDn.equals(dn)) {
-                                               systemRolesConf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null);
-                                       } else {
-                                               AttributesDictionary dico = new AttributesDictionary(deployConfig);
-                                               conf.update(dico);
-                                       }
-                               }
-                       }
-               }
-
-               // system roles must be last since it triggers node user admin publication
-               if (systemRolesConf == null)
-                       throw new IllegalStateException("System roles are not configured.");
-               systemRolesConf.update(new AttributesDictionary(deployConfigs.get(systemRolesDn)));
-
-//             logAllConfigurations();
-       }
-
-       public Set<Dictionary<String, Object>> getUserDirectoryConfigs() {
-               // not static because class is not supported by Android
-               final LdapName USER_ADMIN_BASE_DN;
-               try {
-                       USER_ADMIN_BASE_DN = new LdapName(
-                                       CmsConstants.OU + "=" + CmsConstants.NODE_USER_ADMIN_PID + "," + CmsConstants.DEPLOY_BASEDN);
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException(e);
-               }
-               Set<Dictionary<String, Object>> res = new HashSet<>();
-               for (LdapName dn : deployConfigs.keySet()) {
-                       if (dn.endsWith(USER_ADMIN_BASE_DN)) {
-                               Attributes attributes = deployConfigs.get(dn);
-                               res.add(new AttributesDictionary(attributes));
-                       }
-               }
-               return res;
-       }
-
-//     @Override
-       public void configurationEvent(ConfigurationEvent event) {
-               try {
-                       if (ConfigurationEvent.CM_UPDATED == event.getType()) {
-                               Configuration conf = configurationAdmin.getConfiguration(event.getPid(), null);
-                               LdapName serviceDn = null;
-                               String factoryPid = conf.getFactoryPid();
-                               if (factoryPid != null) {
-                                       LdapName serviceFactoryDn = serviceFactoryDn(factoryPid);
-                                       if (deployConfigs.containsKey(serviceFactoryDn)) {
-                                               for (LdapName dn : deployConfigs.keySet()) {
-                                                       if (dn.startsWith(serviceFactoryDn)) {
-                                                               Rdn lastRdn = dn.getRdn(dn.size() - 1);
-                                                               assert lastRdn.getType().equals(CmsConstants.CN);
-                                                               Object value = conf.getProperties().get(lastRdn.getType());
-                                                               assert value != null;
-                                                               if (value.equals(lastRdn.getValue())) {
-                                                                       serviceDn = dn;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-
-                                               Object cn = conf.getProperties().get(CmsConstants.CN);
-                                               if (cn == null)
-                                                       throw new IllegalArgumentException("Properties must contain cn");
-                                               if (serviceDn == null) {
-                                                       putFactoryDeployConfig(factoryPid, conf.getProperties());
-                                               } else {
-                                                       Attributes attrs = deployConfigs.get(serviceDn);
-                                                       assert attrs != null;
-                                                       AttributesDictionary.copy(conf.getProperties(), attrs);
-                                               }
-                                               save();
-                                               if (log.isDebugEnabled())
-                                                       log.debug("Updated deploy config " + serviceDn(factoryPid, cn.toString()));
-                                       } else {
-                                               // ignore non config-registered service factories
-                                       }
-                               } else {
-                                       serviceDn = serviceDn(event.getPid());
-                                       if (deployConfigs.containsKey(serviceDn)) {
-                                               Attributes attrs = deployConfigs.get(serviceDn);
-                                               assert attrs != null;
-                                               AttributesDictionary.copy(conf.getProperties(), attrs);
-                                               save();
-                                               if (log.isDebugEnabled())
-                                                       log.debug("Updated deploy config " + serviceDn);
-                                       } else {
-                                               // ignore non config-registered services
-                                       }
-                               }
-                       }
-               } catch (Exception e) {
-                       log.error("Could not handle configuration event", e);
-               }
-       }
-
-       public void putFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props) {
-               Object cn = props.get(CmsConstants.CN);
-               if (cn == null)
-                       throw new IllegalArgumentException("cn must be set in properties");
-               LdapName serviceFactoryDn = serviceFactoryDn(factoryPid);
-               if (!deployConfigs.containsKey(serviceFactoryDn))
-                       deployConfigs.put(serviceFactoryDn, new BasicAttributes(CmsConstants.OU, factoryPid));
-               LdapName serviceDn = serviceDn(factoryPid, cn.toString());
-               Attributes attrs = new BasicAttributes();
-               AttributesDictionary.copy(props, attrs);
-               deployConfigs.put(serviceDn, attrs);
-       }
-
-       void putDeployConfig(String servicePid, Dictionary<String, Object> props) {
-               LdapName serviceDn = serviceDn(servicePid);
-               Attributes attrs = new BasicAttributes(CmsConstants.CN, servicePid);
-               AttributesDictionary.copy(props, attrs);
-               deployConfigs.put(serviceDn, attrs);
-       }
-
-       public void save() {
-               try (Writer writer = Files.newBufferedWriter(deployConfigPath)) {
-                       new LdifWriter(writer).write(deployConfigs);
-               } catch (IOException e) {
-                       // throw new CmsException("Cannot save deploy configs", e);
-                       log.error("Cannot save deploy configs", e);
-               }
-       }
-
-       public void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
-               this.configurationAdmin = configurationAdmin;
-       }
-
-       public boolean hasDomain() {
-               // FIXME lookup deploy configs directly
-               if (configurationAdmin == null)
-                       return false;
-
-               Configuration[] configs = listConfigurationsByFactory(CmsConstants.NODE_USER_ADMIN_PID);
-
-               boolean hasDomain = false;
-               for (Configuration config : configs) {
-                       Object realm = config.getProperties().get(DirectoryConf.realm.name());
-                       if (realm != null) {
-                               log.debug("Found realm: " + realm);
-                               hasDomain = true;
-                       }
-               }
-               return hasDomain;
-       }
-
-       private Configuration[] listConfigurationsByFactory(String factoryPid) {
-               try {
-                       Configuration[] configs = configurationAdmin.listConfigurations("(service.factoryPid=" + factoryPid + ")");
-                       if (configs == null)
-                               configs = new Configuration[0];
-                       return configs;
-               } catch (IOException | InvalidSyntaxException e) {
-                       throw new IllegalStateException("Cannot list configurations with factoryPid " + factoryPid, e);
-               }
-
-       }
-
-       private Configuration getSingleServiceConfiguration(String factoryPid, String cn) {
-               Configuration[] configs = listConfigurationsByFactory(factoryPid);
-               List<Configuration> res = new ArrayList<>();
-               for (Configuration config : configs) {
-                       Object currentCn = config.getProperties().get(CmsConstants.CN);
-                       if (currentCn != null && cn.equals(currentCn.toString()))
-                               res.add(config);
-               }
-               if (res.size() == 0)
-                       return null;
-               if (res.size() > 1)
-                       throw new IllegalStateException(
-                                       "More than one " + factoryPid + " configuration returned for " + CmsConstants.CN + "=" + cn);
-               return res.get(0);
-       }
-
-       /*
-        * UTILITIES
-        */
-       private LdapName serviceFactoryDn(String factoryPid) {
-               try {
-                       return new LdapName(CmsConstants.OU + "=" + factoryPid + "," + CmsConstants.DEPLOY_BASEDN);
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Cannot generate DN from " + factoryPid, e);
-               }
-       }
-
-       private LdapName serviceDn(String servicePid) {
-               try {
-                       return new LdapName(CmsConstants.CN + "=" + servicePid + "," + CmsConstants.DEPLOY_BASEDN);
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Cannot generate DN from " + servicePid, e);
-               }
-       }
-
-       private LdapName serviceDn(String factoryPid, String cn) {
-               try {
-                       return (LdapName) serviceFactoryDn(factoryPid).add(new Rdn(CmsConstants.CN, cn));
-               } catch (InvalidNameException e) {
-                       throw new IllegalArgumentException("Cannot generate DN from " + factoryPid + " and " + cn, e);
-               }
-       }
-
-       public Dictionary<String, Object> getProps(String factoryPid, String cn) {
-               Attributes attrs = deployConfigs.get(serviceDn(factoryPid, cn));
-               if (attrs != null)
-                       return new AttributesDictionary(attrs);
-               else
-                       return null;
-       }
-
-       private static boolean isInitialized() {
-               return Files.exists(deployConfigPath);
-       }
-
-       public boolean isFirstInit() {
-               return isFirstInit;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/osgi/NodeUserAdmin.java b/org.argeo.cms/src/org/argeo/cms/internal/osgi/NodeUserAdmin.java
deleted file mode 100644 (file)
index da67c73..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.argeo.cms.internal.osgi;
-
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.internal.runtime.CmsUserAdmin;
-import org.argeo.osgi.useradmin.UserDirectory;
-import org.argeo.util.directory.DirectoryConf;
-import org.osgi.framework.Constants;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.osgi.service.useradmin.UserAdmin;
-
-/**
- * Aggregates multiple {@link UserDirectory} and integrates them with system
- * roles.
- */
-@Deprecated
-public class NodeUserAdmin extends CmsUserAdmin implements ManagedServiceFactory {
-       private final static CmsLog log = CmsLog.getLog(NodeUserAdmin.class);
-
-       // OSGi
-       private Map<String, String> pidToBaseDn = new HashMap<>();
-
-       @Override
-       public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
-
-               String basePath = (String) properties.get(DirectoryConf.baseDn.name());
-
-               // FIXME make updates more robust
-               if (pidToBaseDn.containsValue(basePath)) {
-                       if (log.isDebugEnabled())
-                               log.debug("Ignoring user directory update of " + basePath);
-                       return;
-               }
-
-               UserDirectory userDirectory = enableUserDirectory(properties);
-               // OSGi
-               Hashtable<String, Object> regProps = new Hashtable<>();
-               regProps.put(Constants.SERVICE_PID, pid);
-               if (isSystemRolesBaseDn(basePath))
-                       regProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
-               regProps.put(DirectoryConf.baseDn.name(), basePath);
-
-               CmsActivator.getBundleContext().registerService(UserDirectory.class, userDirectory, regProps);
-               pidToBaseDn.put(pid, basePath);
-
-               if (isSystemRolesBaseDn(basePath)) {
-                       // publishes itself as user admin only when system roles are available
-                       Dictionary<String, Object> userAdminregProps = new Hashtable<>();
-                       userAdminregProps.put(CmsConstants.CN, CmsConstants.DEFAULT);
-                       userAdminregProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
-                       CmsActivator.getBundleContext().registerService(UserAdmin.class, this, userAdminregProps);
-               }
-       }
-
-       @Override
-       public void deleted(String pid) {
-               // assert pidToServiceRegs.get(pid) != null;
-               assert pidToBaseDn.get(pid) != null;
-               // pidToServiceRegs.remove(pid).unregister();
-               String basePath = pidToBaseDn.remove(pid);
-               removeUserDirectory(basePath);
-       }
-
-       @Override
-       public String getName() {
-               return "Node User Admin";
-       }
-
-}
index 8b0fbbc6862f9b94b3a0ae176d5cb6f81daa7290..497ed923fa5f9ee2ae9bd46890f27ce39eae7754 100644 (file)
@@ -1,7 +1,11 @@
 package org.argeo.cms.internal.runtime;
 
+import static org.argeo.api.cms.CmsConstants.CONTEXT_PATH;
+
 import java.util.Map;
+import java.util.TreeMap;
 
+import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsDeployment;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsState;
@@ -15,13 +19,14 @@ public class CmsDeploymentImpl implements CmsDeployment {
        private final CmsLog log = CmsLog.getLog(getClass());
 
        // Readiness
-       private boolean httpExpected = false;
 //     private HttpService httpService;
 
        private CmsState cmsState;
 //     private DeployConfig deployConfig;
 
+       private boolean httpExpected = false;
        private HttpServer httpServer;
+       private Map<String, HttpHandler> httpHandlers = new TreeMap<>();
 
        public void start() {
 //             httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
@@ -78,21 +83,35 @@ public class CmsDeploymentImpl implements CmsDeployment {
 
        public void setHttpServer(HttpServer httpServer) {
                this.httpServer = httpServer;
+               // create contexts whose handles had already been published
+               for (String contextPath : httpHandlers.keySet()) {
+                       HttpHandler httpHandler = httpHandlers.get(contextPath);
+                       httpServer.createContext(contextPath, httpHandler);
+                       log.debug(() -> "Added handler " + contextPath + " : " + httpHandler.getClass().getName());
+               }
        }
 
        public void addHttpHandler(HttpHandler httpHandler, Map<String, String> properties) {
+               final String contextPath = properties.get(CONTEXT_PATH);
+               if (contextPath == null) {
+                       log.warn("Property " + CONTEXT_PATH + " not set on HTTP handler " + properties + ". Ignoring it.");
+                       return;
+               }
+               httpHandlers.put(contextPath, httpHandler);
                if (httpServer == null)
                        return;
-               final String contextPath = properties.get("contextPath");
                httpServer.createContext(contextPath, httpHandler);
                log.debug(() -> "Added handler " + contextPath + " : " + httpHandler.getClass().getName());
 
        }
 
        public void removeHttpHandler(HttpHandler httpHandler, Map<String, String> properties) {
+               final String contextPath = properties.get(CmsConstants.CONTEXT_PATH);
+               if (contextPath == null)
+                       return; // ignore silently
+               httpHandlers.remove(contextPath);
                if (httpServer == null)
                        return;
-               final String contextPath = properties.get("contextPath");
                httpServer.removeContext(contextPath);
                log.debug(() -> "Removed handler " + contextPath + " : " + httpHandler.getClass().getName());
        }
index 7252f425fd6f5544d92d47316bdf1f6596c789f0..d335b48b191b111ce428ac2bab5dc19beff228e8 100644 (file)
@@ -4,9 +4,7 @@ import java.io.File;
 import java.io.FileFilter;
 import java.io.IOException;
 import java.io.Reader;
-import java.net.InetAddress;
 import java.net.URL;
-import java.net.UnknownHostException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -119,7 +117,7 @@ public class CmsStateImpl implements CmsState {
                        }
 
                } catch (RuntimeException | IOException e) {
-                       log.error("## FATAL: CMS activator failed", e);
+                       log.error("## FATAL: CMS state failed", e);
                }
        }