/******************************************************************************* * Copyright (c) 2005, 2006 IBM Corporation 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.gecko.runtime.application.internal; import java.security.Guard; import java.security.GuardedObject; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceRegistration; import org.osgi.service.application.ApplicationDescriptor; import org.osgi.service.application.ScheduledApplication; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; import org.osgi.service.event.TopicPermission; public class GeckoScheduledApplication implements ScheduledApplication, EventHandler { private static Logger logger = Logger.getLogger("org.gecko.scheduledApplication"); private static final String FILTER_PREFIX = "(&(objectclass=" + ApplicationDescriptor.class.getName() + ")(" + ApplicationDescriptor.APPLICATION_PID + "="; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ private static final String FILTER_POSTFIX = "))"; //$NON-NLS-1$ private boolean recurring; private String topic; private String eventFilter; @SuppressWarnings("rawtypes") private Map args; private String applicationPid; private String id; private ServiceRegistration registration; private SecureServiceTracker appDescTracker; private volatile boolean removed = false; @SuppressWarnings("rawtypes") GeckoScheduledApplication(BundleContext context, String id, String appPid, Map args, String topic, String eventFilter, boolean recurring) throws InvalidSyntaxException { this.id = id; this.applicationPid = appPid; this.args = args; this.topic = topic == null || topic.trim().equals("") || topic.trim().equals("*") ? null : topic; //$NON-NLS-1$ //$NON-NLS-2$ this.eventFilter = eventFilter; this.recurring = recurring; appDescTracker = new SecureServiceTracker<>(context, context.createFilter(FILTER_PREFIX + appPid + FILTER_POSTFIX)); appDescTracker.open(false); } /* * (non-Javadoc) * @see org.osgi.service.application.ScheduledApplication#getScheduleId() */ public String getScheduleId() { return id; } /* * (non-Javadoc) * @see org.osgi.service.application.ScheduledApplication#getTopic() */ public synchronized String getTopic() { if (removed) throw new IllegalStateException("Application has been unregistered"); return topic; } /* * (non-Javadoc) * @see org.osgi.service.application.ScheduledApplication#getEventFilter() */ public synchronized String getEventFilter() { if (removed) throw new IllegalStateException("Application has been unregistered"); return eventFilter; } /* * (non-Javadoc) * @see org.osgi.service.application.ScheduledApplication#isRecurring() */ public synchronized boolean isRecurring() { if (removed) throw new IllegalStateException("Application has been unregistered"); return recurring; } /* * (non-Javadoc) * @see org.osgi.service.application.ScheduledApplication#getApplicationDescriptor() */ public synchronized ApplicationDescriptor getApplicationDescriptor() { if (removed) throw new IllegalStateException("Application has been unregistered"); return appDescTracker.getService(); } /* * (non-Javadoc) * @see org.osgi.service.application.ScheduledApplication#getArguments() */ @SuppressWarnings({ "rawtypes", "unchecked" }) public synchronized Map getArguments() { if (removed) throw new IllegalStateException("Application has been unregistered"); return args == null ? null : new HashMap(args); } /* * (non-Javadoc) * @see org.osgi.service.application.ScheduledApplication#remove() */ public synchronized void remove() { if (removed) { return; } removed = true; // AppPersistence.removeScheduledApp(this); if (registration != null) registration.unregister(); registration = null; appDescTracker.close(); } /* * (non-Javadoc) * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event) */ public synchronized void handleEvent(Event event) { try { if (removed) { return; } ApplicationDescriptor desc = getApplicationDescriptor(); if (desc == null) // in this case the application descriptor was removed; // we must return and keep the scheduled application in case the application comes back return; desc.launch(getArguments(event)); } catch (Exception e) { logger.log(Level.WARNING, "Failed to launch the scheduled application: " + getApplicationDescriptor().getApplicationId()); // return here to avoid removing non-recurring applications when an error occurs return; } if (!isRecurring()) remove(); } /** * Returns the application id * @return the application id */ public Object getApplicationPid() { return applicationPid; } /** * Sets the service registration for the {@link ScheduledApplication} * @param registration the service registration */ synchronized void setServiceRegistration(ServiceRegistration registration) { this.registration = registration; // just in case we were removed before the registration was set if (removed) { registration.unregister(); } } /** * Returns the arguments for a trigger event * @param trigger the trigger event * @return the arguments map */ @SuppressWarnings({ "rawtypes", "unchecked" }) private Map getArguments(Event trigger) { Map result = args == null ? new HashMap() : getArguments(); result.put(TRIGGERING_EVENT, new GuardedObject(trigger, new TriggerGuard(trigger.getTopic()))); return result; } /* * This is used to guard the event topic argument which is passed to an application * when we are launching it from a scheduling. */ public class TriggerGuard implements Guard { String eventTopic; public TriggerGuard(String topic) { this.eventTopic = topic; } /* * does the proper TopicPermission check for the event topic */ public void checkGuard(Object object) throws SecurityException { SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(new TopicPermission(eventTopic, TopicPermission.SUBSCRIBE)); } } }