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
.cms
.CmsException
;
19 import org
.argeo
.cms
.LocaleUtils
;
20 import org
.argeo
.node
.NodeConstants
;
21 import org
.argeo
.node
.NodeState
;
22 import org
.argeo
.transaction
.simple
.SimpleTransactionManager
;
23 import org
.argeo
.util
.LangUtils
;
24 import org
.osgi
.framework
.BundleContext
;
25 import org
.osgi
.framework
.Constants
;
26 import org
.osgi
.framework
.FrameworkUtil
;
27 import org
.osgi
.service
.cm
.ManagedServiceFactory
;
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
;
48 public CmsState(String stateUuid
) {
49 this.stateUuid
= stateUuid
;
50 String frameworkUuid
= 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 ?
" (clean state) " : " "));
66 kernelThread
= new KernelThread(threadGroup
, "Kernel Thread");
67 kernelThread
.setContextClassLoader(getClass().getClassLoader());
71 private void initI18n() {
72 Object defaultLocaleValue
= KernelUtils
.getFrameworkProp(NodeConstants
.I18N_DEFAULT_LOCALE
);
73 defaultLocale
= defaultLocaleValue
!= null ?
new Locale(defaultLocaleValue
.toString())
74 : new Locale(ENGLISH
.getLanguage());
75 locales
= LocaleUtils
.asLocaleList(KernelUtils
.getFrameworkProp(NodeConstants
.I18N_LOCALES
));
78 private void initServices() {
80 String tmType
= KernelUtils
.getFrameworkProp(NodeConstants
.TRANSACTION_MANAGER
,
81 NodeConstants
.TRANSACTION_MANAGER_SIMPLE
);
82 if (NodeConstants
.TRANSACTION_MANAGER_SIMPLE
.equals(tmType
)) {
83 initSimpleTransactionManager();
84 } else if (NodeConstants
.TRANSACTION_MANAGER_BITRONIX
.equals(tmType
)) {
85 // initBitronixTransactionManager();
86 throw new UnsupportedOperationException(
87 "Bitronix is not supported anymore, but could be again if there is enough interest.");
89 throw new CmsException("Usupported transaction manager type " + tmType
);
93 // POIXMLTypeLoader.setClassLoader(CTConnection.class.getClassLoader());
96 // OpenDocumentParser odfParser = new OpenDocumentParser();
97 // bc.registerService(Parser.class, odfParser, new Hashtable());
98 // PDFParser pdfParser = new PDFParser();
99 // bc.registerService(Parser.class, pdfParser, new Hashtable());
100 // OOXMLParser ooxmlParser = new OOXMLParser();
101 // bc.registerService(Parser.class, ooxmlParser, new Hashtable());
102 // TesseractOCRParser ocrParser = new TesseractOCRParser();
103 // ocrParser.setLanguage("ara");
104 // bc.registerService(Parser.class, ocrParser, new Hashtable());
107 RepositoryServiceFactory repositoryServiceFactory
= new RepositoryServiceFactory();
108 stopHooks
.add(() -> repositoryServiceFactory
.shutdown());
109 bc
.registerService(ManagedServiceFactory
.class, repositoryServiceFactory
,
110 LangUtils
.dico(Constants
.SERVICE_PID
, NodeConstants
.NODE_REPOS_FACTORY_PID
));
112 NodeRepositoryFactory repositoryFactory
= new NodeRepositoryFactory();
113 bc
.registerService(RepositoryFactory
.class, repositoryFactory
, null);
116 NodeUserAdmin userAdmin
= new NodeUserAdmin(NodeConstants
.ROLES_BASEDN
);
117 stopHooks
.add(() -> userAdmin
.destroy());
118 bc
.registerService(ManagedServiceFactory
.class, userAdmin
,
119 LangUtils
.dico(Constants
.SERVICE_PID
, NodeConstants
.NODE_USER_ADMIN_PID
));
122 CmsFsProvider cmsFsProvider
= new CmsFsProvider();
123 // ServiceLoader<FileSystemProvider> fspSl = ServiceLoader.load(FileSystemProvider.class);
124 // for (FileSystemProvider fsp : fspSl) {
125 // log.debug("FileSystemProvider " + fsp);
126 // if (fsp instanceof CmsFsProvider) {
127 // cmsFsProvider = (CmsFsProvider) fsp;
130 // for (FileSystemProvider fsp : FileSystemProvider.installedProviders()) {
131 // log.debug("Installed FileSystemProvider " + fsp);
133 bc
.registerService(FileSystemProvider
.class, cmsFsProvider
,
134 LangUtils
.dico(Constants
.SERVICE_PID
, NodeConstants
.NODE_FS_PROVIDER_PID
));
137 private void initSimpleTransactionManager() {
138 SimpleTransactionManager transactionManager
= new SimpleTransactionManager();
139 bc
.registerService(TransactionManager
.class, transactionManager
, null);
140 bc
.registerService(UserTransaction
.class, transactionManager
, null);
141 // TODO TransactionSynchronizationRegistry
144 // private void initBitronixTransactionManager() {
145 // // TODO manage it in a managed service, as startup could be long
146 // ServiceReference<TransactionManager> existingTm = bc.getServiceReference(TransactionManager.class);
147 // if (existingTm != null) {
148 // if (log.isDebugEnabled())
149 // log.debug("Using provided transaction manager " + existingTm);
153 // if (!TransactionManagerServices.isTransactionManagerRunning()) {
154 // bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration();
155 // tmConf.setServerId(UUID.randomUUID().toString());
157 // Bundle bitronixBundle = FrameworkUtil.getBundle(bitronix.tm.Configuration.class);
158 // File tmBaseDir = bitronixBundle.getDataFile(KernelConstants.DIR_TRANSACTIONS);
159 // File tmDir1 = new File(tmBaseDir, "btm1");
161 // tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath());
162 // File tmDir2 = new File(tmBaseDir, "btm2");
164 // tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath());
166 // BitronixTransactionManager transactionManager = getTransactionManager();
167 // stopHooks.add(() -> transactionManager.shutdown());
168 // BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry = getTransactionSynchronizationRegistry();
170 // bc.registerService(TransactionManager.class, transactionManager, null);
171 // bc.registerService(UserTransaction.class, transactionManager, null);
172 // bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null);
173 // if (log.isDebugEnabled())
174 // log.debug("Initialised default Bitronix transaction manager");
178 if (log
.isDebugEnabled())
179 log
.debug("CMS stopping... stateUuid=" + this.stateUuid
+ (cleanState ?
" (clean state) " : " "));
181 if (kernelThread
!= null)
182 kernelThread
.destroyAndJoin();
183 // In a different state in order to avois interruptions
184 new Thread(() -> applyStopHooks(), "Apply Argeo Stop Hooks").start();
187 long duration
= ((System
.currentTimeMillis() - availableSince
) / 1000) / 60;
188 log
.info("## ARGEO CMS STOPPED after " + (duration
/ 60) + "h " + (duration
% 60) + "min uptime ##");
191 /** Apply shutdown hoos in reverse order. */
192 private void applyStopHooks() {
193 for (int i
= stopHooks
.size() - 1; i
>= 0; i
--) {
195 stopHooks
.get(i
).run();
196 } catch (Exception e
) {
197 log
.error("Could not run shutdown hook #" + i
);
200 // Clean hanging Gogo shell thread
201 new GogoShellKiller().start();
205 public boolean isClean() {
210 public Long
getAvailableSince() {
211 return availableSince
;
217 public Locale
getDefaultLocale() {
218 return defaultLocale
;
221 public List
<Locale
> getLocales() {
225 public String
getHostname() {