1 package org
.argeo
.cms
.internal
.kernel
;
3 import static java
.util
.Locale
.ENGLISH
;
5 import java
.net
.InetAddress
;
6 import java
.net
.UnknownHostException
;
7 import java
.nio
.file
.spi
.FileSystemProvider
;
8 import java
.util
.ArrayList
;
10 import java
.util
.Locale
;
12 import javax
.jcr
.RepositoryFactory
;
13 import javax
.transaction
.TransactionManager
;
14 import javax
.transaction
.UserTransaction
;
16 import org
.apache
.commons
.logging
.Log
;
17 import org
.apache
.commons
.logging
.LogFactory
;
18 import org
.argeo
.api
.NodeConstants
;
19 import org
.argeo
.api
.NodeState
;
20 import org
.argeo
.cms
.LocaleUtils
;
21 import org
.argeo
.transaction
.simple
.SimpleTransactionManager
;
22 import org
.argeo
.util
.LangUtils
;
23 import org
.osgi
.framework
.Constants
;
24 import org
.osgi
.service
.cm
.ManagedServiceFactory
;
27 * Implementation of a {@link NodeState}, initialising the required services.
29 public class CmsState
implements NodeState
{
30 private final static Log log
= LogFactory
.getLog(CmsState
.class);
31 // private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext();
34 private Long availableSince
;
37 private Locale defaultLocale
;
38 private List
<Locale
> locales
= null;
40 private ThreadGroup threadGroup
= new ThreadGroup("CMS");
41 private KernelThread kernelThread
;
42 private List
<Runnable
> stopHooks
= new ArrayList
<>();
44 private final String stateUuid
;
45 // private final boolean cleanState;
46 private String hostname
;
49 // this.stateUuid = stateUuid;
50 this.stateUuid
= KernelUtils
.getFrameworkProp(Constants
.FRAMEWORK_UUID
);
51 // this.cleanState = stateUuid.equals(frameworkUuid);
53 this.hostname
= InetAddress
.getLocalHost().getHostName();
54 } catch (UnknownHostException e
) {
55 log
.error("Cannot set hostname: " + e
);
58 availableSince
= System
.currentTimeMillis();
59 if (log
.isDebugEnabled())
60 // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? "
61 // (clean state) " : " "));
62 log
.debug("## CMS starting... (" + stateUuid
+ ")");
68 kernelThread
= new KernelThread(threadGroup
, "Kernel Thread");
69 kernelThread
.setContextClassLoader(getClass().getClassLoader());
73 private void initI18n() {
74 Object defaultLocaleValue
= KernelUtils
.getFrameworkProp(NodeConstants
.I18N_DEFAULT_LOCALE
);
75 defaultLocale
= defaultLocaleValue
!= null ?
new Locale(defaultLocaleValue
.toString())
76 : new Locale(ENGLISH
.getLanguage());
77 locales
= LocaleUtils
.asLocaleList(KernelUtils
.getFrameworkProp(NodeConstants
.I18N_LOCALES
));
80 private void initServices() {
82 String tmType
= KernelUtils
.getFrameworkProp(NodeConstants
.TRANSACTION_MANAGER
,
83 NodeConstants
.TRANSACTION_MANAGER_SIMPLE
);
84 if (NodeConstants
.TRANSACTION_MANAGER_SIMPLE
.equals(tmType
)) {
85 initSimpleTransactionManager();
86 } else if (NodeConstants
.TRANSACTION_MANAGER_BITRONIX
.equals(tmType
)) {
87 // initBitronixTransactionManager();
88 throw new UnsupportedOperationException(
89 "Bitronix is not supported anymore, but could be again if there is enough interest.");
91 throw new IllegalArgumentException("Usupported transaction manager type " + tmType
);
95 // POIXMLTypeLoader.setClassLoader(CTConnection.class.getClassLoader());
98 // OpenDocumentParser odfParser = new OpenDocumentParser();
99 // bc.registerService(Parser.class, odfParser, new Hashtable());
100 // PDFParser pdfParser = new PDFParser();
101 // bc.registerService(Parser.class, pdfParser, new Hashtable());
102 // OOXMLParser ooxmlParser = new OOXMLParser();
103 // bc.registerService(Parser.class, ooxmlParser, new Hashtable());
104 // TesseractOCRParser ocrParser = new TesseractOCRParser();
105 // ocrParser.setLanguage("ara");
106 // bc.registerService(Parser.class, ocrParser, new Hashtable());
109 RepositoryServiceFactory repositoryServiceFactory
= new RepositoryServiceFactory();
110 stopHooks
.add(() -> repositoryServiceFactory
.shutdown());
111 Activator
.registerService(ManagedServiceFactory
.class, repositoryServiceFactory
,
112 LangUtils
.dict(Constants
.SERVICE_PID
, NodeConstants
.NODE_REPOS_FACTORY_PID
));
114 NodeRepositoryFactory repositoryFactory
= new NodeRepositoryFactory();
115 Activator
.registerService(RepositoryFactory
.class, repositoryFactory
, null);
118 NodeUserAdmin userAdmin
= new NodeUserAdmin(NodeConstants
.ROLES_BASEDN
, NodeConstants
.TOKENS_BASEDN
);
119 stopHooks
.add(() -> userAdmin
.destroy());
120 Activator
.registerService(ManagedServiceFactory
.class, userAdmin
,
121 LangUtils
.dict(Constants
.SERVICE_PID
, NodeConstants
.NODE_USER_ADMIN_PID
));
124 CmsFsProvider cmsFsProvider
= new CmsFsProvider();
125 // ServiceLoader<FileSystemProvider> fspSl = ServiceLoader.load(FileSystemProvider.class);
126 // for (FileSystemProvider fsp : fspSl) {
127 // log.debug("FileSystemProvider " + fsp);
128 // if (fsp instanceof CmsFsProvider) {
129 // cmsFsProvider = (CmsFsProvider) fsp;
132 // for (FileSystemProvider fsp : FileSystemProvider.installedProviders()) {
133 // log.debug("Installed FileSystemProvider " + fsp);
135 Activator
.registerService(FileSystemProvider
.class, cmsFsProvider
,
136 LangUtils
.dict(Constants
.SERVICE_PID
, NodeConstants
.NODE_FS_PROVIDER_PID
));
139 private void initSimpleTransactionManager() {
140 SimpleTransactionManager transactionManager
= new SimpleTransactionManager();
141 Activator
.registerService(TransactionManager
.class, transactionManager
, null);
142 Activator
.registerService(UserTransaction
.class, transactionManager
, null);
143 // TODO TransactionSynchronizationRegistry
146 // private void initBitronixTransactionManager() {
147 // // TODO manage it in a managed service, as startup could be long
148 // ServiceReference<TransactionManager> existingTm = bc.getServiceReference(TransactionManager.class);
149 // if (existingTm != null) {
150 // if (log.isDebugEnabled())
151 // log.debug("Using provided transaction manager " + existingTm);
155 // if (!TransactionManagerServices.isTransactionManagerRunning()) {
156 // bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration();
157 // tmConf.setServerId(UUID.randomUUID().toString());
159 // Bundle bitronixBundle = FrameworkUtil.getBundle(bitronix.tm.Configuration.class);
160 // File tmBaseDir = bitronixBundle.getDataFile(KernelConstants.DIR_TRANSACTIONS);
161 // File tmDir1 = new File(tmBaseDir, "btm1");
163 // tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath());
164 // File tmDir2 = new File(tmBaseDir, "btm2");
166 // tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath());
168 // BitronixTransactionManager transactionManager = getTransactionManager();
169 // stopHooks.add(() -> transactionManager.shutdown());
170 // BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry = getTransactionSynchronizationRegistry();
172 // bc.registerService(TransactionManager.class, transactionManager, null);
173 // bc.registerService(UserTransaction.class, transactionManager, null);
174 // bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null);
175 // if (log.isDebugEnabled())
176 // log.debug("Initialised default Bitronix transaction manager");
180 if (log
.isDebugEnabled())
181 log
.debug("CMS stopping... (" + this.stateUuid
+ ")");
183 if (kernelThread
!= null)
184 kernelThread
.destroyAndJoin();
185 // In a different thread in order to avoid interruptions
186 Thread stopHookThread
= new Thread(() -> applyStopHooks(), "Apply Argeo Stop Hooks");
187 stopHookThread
.start();
189 stopHookThread
.join(10 * 60 * 1000);
190 } catch (InterruptedException e
) {
194 long duration
= ((System
.currentTimeMillis() - availableSince
) / 1000) / 60;
195 log
.info("## ARGEO CMS STOPPED after " + (duration
/ 60) + "h " + (duration
% 60) + "min uptime ##");
198 /** Apply shutdown hoos in reverse order. */
199 private void applyStopHooks() {
200 for (int i
= stopHooks
.size() - 1; i
>= 0; i
--) {
202 stopHooks
.get(i
).run();
203 } catch (Exception e
) {
204 log
.error("Could not run shutdown hook #" + i
);
207 // Clean hanging Gogo shell thread
208 new GogoShellKiller().start();
212 // public boolean isClean() {
213 // return cleanState;
217 public Long
getAvailableSince() {
218 return availableSince
;
224 public Locale
getDefaultLocale() {
225 return defaultLocale
;
228 public List
<Locale
> getLocales() {
232 public String
getHostname() {