/*******************************************************************************
* Copyright (c) 2016 Weasis Team and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nicolas Roduit - initial API and implementation
*******************************************************************************/
package org.weasis.core.api.internal;
import java.awt.RenderingHints;
import java.io.File;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.media.jai.JAI;
import javax.media.jai.OperationRegistry;
import javax.media.jai.RecyclingTileFactory;
import javax.media.jai.TileScheduler;
import org.apache.felix.prefs.BackingStore;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.weasis.core.api.gui.util.AppProperties;
import org.weasis.core.api.image.op.FormatBinaryDescriptor;
import org.weasis.core.api.image.op.ImageStatistics2Descriptor;
import org.weasis.core.api.image.op.ImageStatisticsDescriptor;
import org.weasis.core.api.image.op.NotBinaryDescriptor;
import org.weasis.core.api.image.op.RectifySignedShortDataDescriptor;
import org.weasis.core.api.image.op.RectifyUShortToShortDataDescriptor;
import org.weasis.core.api.image.op.ShutterDescriptor;
import org.weasis.core.api.image.op.ThresholdToBinDescriptor;
import org.weasis.core.api.image.util.JAIUtil;
import org.weasis.core.api.media.data.Codec;
import org.weasis.core.api.service.AuditLog;
import org.weasis.core.api.service.BundleTools;
import org.weasis.core.api.service.DataFileBackingStoreImpl;
import org.weasis.core.api.util.ProxyDetector;
public class Activator implements BundleActivator, ServiceListener {
private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class);
@Override
public void start(BundleContext bundleContext) throws Exception {
bundleContext.registerService(BackingStore.class.getName(), new DataFileBackingStoreImpl(bundleContext), null);
for (ServiceReference<Codec> service : bundleContext.getServiceReferences(Codec.class, null)) {
registerCodecPlugins(bundleContext.getService(service));
}
bundleContext.addServiceListener(this, String.format("(%s=%s)", Constants.OBJECTCLASS, Codec.class.getName()));//$NON-NLS-1$
JAI jai = JAIUtil.getJAI();
OperationRegistry or = jai.getOperationRegistry();
jai.setImagingListener((String message, Throwable thrown, Object where, boolean isRetryable) -> {
LOGGER.error("JAI Error in {}: {}", where, message, thrown); //$NON-NLS-1$
return false;
});
JAIUtil.registerOp(or, new FormatBinaryDescriptor());
JAIUtil.registerOp(or, new NotBinaryDescriptor());
JAIUtil.registerOp(or, new ImageStatisticsDescriptor());
JAIUtil.registerOp(or, new ImageStatistics2Descriptor());
JAIUtil.registerOp(or, new ShutterDescriptor());
JAIUtil.registerOp(or, new ThresholdToBinDescriptor());
JAIUtil.registerOp(or, new RectifySignedShortDataDescriptor());
JAIUtil.registerOp(or, new RectifyUShortToShortDataDescriptor());
// Set 1/4 of the total memory for TileCache
jai.getTileCache().setMemoryCapacity(Runtime.getRuntime().maxMemory() / 4);
RecyclingTileFactory recyclingTileFactory = new RecyclingTileFactory();
RenderingHints rh = jai.getRenderingHints();
rh.put(JAI.KEY_TILE_FACTORY, recyclingTileFactory);
rh.put(JAI.KEY_TILE_RECYCLER, recyclingTileFactory);
rh.put(JAI.KEY_CACHED_TILE_RECYCLING_ENABLED, Boolean.TRUE);
jai.setRenderingHints(rh);
TileScheduler scheduler = jai.getTileScheduler();
int nbThread = Math.max(2, Runtime.getRuntime().availableProcessors() - 1);
scheduler.setParallelism(nbThread);
scheduler.setPrefetchParallelism(nbThread - 1);
// Trick for avoiding 403 error when downloading from some web sites
System.setProperty("http.agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"); //$NON-NLS-1$ //$NON-NLS-2$
// Allows to connect through a proxy initialized by Java Webstart
ProxyDetector.setProxyFromJavaWebStart();
initLoggerAndAudit(bundleContext);
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
// TODO should be stop in after all bundles implementing preferences
}
@Override
public synchronized void serviceChanged(ServiceEvent event) {
ServiceReference<?> sRef = event.getServiceReference();
BundleContext context = sRef.getBundle().getBundleContext();
Codec codec = null;
try {
codec = (Codec) context.getService(sRef);
} catch (RuntimeException e) {
// TODO find why sometimes service cannot be returned
LOGGER.info("Cannot get service of {}", sRef.getBundle()); //$NON-NLS-1$
}
if (codec == null) {
return;
}
// TODO manage when several identical MimeType, register the default one
if (event.getType() == ServiceEvent.REGISTERED) {
registerCodecPlugins(codec);
} else if (event.getType() == ServiceEvent.UNREGISTERING) {
if (BundleTools.CODEC_PLUGINS.contains(codec)) {
LOGGER.info("Unregister Image Codec Plug-in: {}", codec.getCodecName()); //$NON-NLS-1$
BundleTools.CODEC_PLUGINS.remove(codec);
}
// Unget service object and null references.
context.ungetService(sRef);
}
}
private static void registerCodecPlugins(Codec codec) {
if (codec != null && !BundleTools.CODEC_PLUGINS.contains(codec)) {
BundleTools.CODEC_PLUGINS.add(codec);
LOGGER.info("Register Image Codec Plug-in: {}", codec.getCodecName()); //$NON-NLS-1$
}
}
private static void initLoggerAndAudit(BundleContext bundleContext) throws IOException {
// Audit log for giving statistics about usage of Weasis
String loggerKey = "audit.log"; //$NON-NLS-1$
String[] loggerVal = new String[] { "org.weasis.core.api.service.AuditLog" }; //$NON-NLS-1$
// Activate audit log by adding an entry "audit.log=true" in Weasis.
if (BundleTools.SYSTEM_PREFERENCES.getBooleanProperty(loggerKey, false)) {
AuditLog.createOrUpdateLogger(bundleContext, loggerKey, loggerVal, "DEBUG", //$NON-NLS-1$
AppProperties.WEASIS_PATH + File.separator + "log" + File.separator + "audit-" //$NON-NLS-1$ //$NON-NLS-2$
+ AppProperties.WEASIS_USER + ".log", //$NON-NLS-1$
"{0,date,dd.MM.yyyy HH:mm:ss.SSS} *{4}* {5}", null, null, "0"); //$NON-NLS-1$ //$NON-NLS-2$
AuditLog.LOGGER.info("Start audit log session"); //$NON-NLS-1$
} else {
ServiceReference<ConfigurationAdmin> configurationAdminReference =
bundleContext.getServiceReference(ConfigurationAdmin.class);
if (configurationAdminReference != null) {
ConfigurationAdmin confAdmin = bundleContext.getService(configurationAdminReference);
if (confAdmin != null) {
Configuration logConfiguration = AuditLog.getLogConfiguration(confAdmin, loggerKey, loggerVal[0]);
if (logConfiguration == null) {
logConfiguration = confAdmin
.createFactoryConfiguration("org.apache.sling.commons.log.LogManager.factory.config", null); //$NON-NLS-1$
Dictionary<String, Object> loggingProperties = new Hashtable<>();
loggingProperties.put("org.apache.sling.commons.log.level", "ERROR"); //$NON-NLS-1$ //$NON-NLS-2$
loggingProperties.put("org.apache.sling.commons.log.names", loggerVal); //$NON-NLS-1$
// add this property to give us something unique to re-find this configuration
loggingProperties.put(loggerKey, loggerVal[0]);
logConfiguration.update(loggingProperties);
}
else {
Dictionary loggingProperties = logConfiguration.getProperties();
loggingProperties.remove(AuditLog.LOG_FILE);
logConfiguration.update(loggingProperties);
}
}
}
}
}
}