Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.app/src/org/eclipse/equinox/internal/app/AppPersistence.java')
-rw-r--r--bundles/org.eclipse.equinox.app/src/org/eclipse/equinox/internal/app/AppPersistence.java430
1 files changed, 0 insertions, 430 deletions
diff --git a/bundles/org.eclipse.equinox.app/src/org/eclipse/equinox/internal/app/AppPersistence.java b/bundles/org.eclipse.equinox.app/src/org/eclipse/equinox/internal/app/AppPersistence.java
deleted file mode 100644
index 055ea77b3..000000000
--- a/bundles/org.eclipse.equinox.app/src/org/eclipse/equinox/internal/app/AppPersistence.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2009 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.eclipse.equinox.internal.app;
-
-import java.io.*;
-import java.util.*;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.eclipse.osgi.service.datalocation.Location;
-import org.eclipse.osgi.storagemanager.StorageManager;
-import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.*;
-import org.osgi.service.application.*;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventConstants;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-/**
- * Manages all persistent data for ApplicationDescriptors (lock status,
- * scheduled applications etc.)
- */
-public class AppPersistence implements ServiceTrackerCustomizer {
- private static final String PROP_CONFIG_AREA = "osgi.configuration.area"; //$NON-NLS-1$
-
- private static final String FILTER_PREFIX = "(&(objectClass=org.eclipse.osgi.service.datalocation.Location)(type="; //$NON-NLS-1$
- private static final String FILE_APPLOCKS = ".locks"; //$NON-NLS-1$
- private static final String FILE_APPSCHEDULED = ".scheduled"; //$NON-NLS-1$
- private static final String EVENT_HANDLER = "org.osgi.service.event.EventHandler"; //$NON-NLS-1$
-
- private static final int DATA_VERSION = 2;
- private static final byte NULL = 0;
- private static final int OBJECT = 1;
-
- private static BundleContext context;
- private static ServiceTracker configTracker;
- private static Location configLocation;
- private static Collection locks = new ArrayList();
- private static Map scheduledApps = new HashMap();
- static ArrayList timerApps = new ArrayList();
- private static StorageManager storageManager;
- private static boolean scheduling = false;
- static boolean shutdown = false;
- private static int nextScheduledID = 1;
- private static Thread timerThread;
-
- static void start(BundleContext bc) {
- context = bc;
- shutdown = false;
- initConfiguration();
- }
-
- static void stop() {
- shutdown = true;
- stopTimer();
- if (storageManager != null) {
- storageManager.close();
- storageManager = null;
- }
- closeConfiguration();
- context = null;
- }
-
- private static void initConfiguration() {
- closeConfiguration(); // just incase
- Filter filter = null;
- try {
- filter = context.createFilter(FILTER_PREFIX + PROP_CONFIG_AREA + "))"); //$NON-NLS-1$
- } catch (InvalidSyntaxException e) {
- // ignore this. It should never happen as we have tested the above format.
- }
- configTracker = new ServiceTracker(context, filter, new AppPersistence());
- configTracker.open();
- }
-
- private static void closeConfiguration() {
- if (configTracker != null)
- configTracker.close();
- configTracker = null;
- }
-
- /**
- * Used by {@link ApplicationDescriptor} to determine if an application is locked.
- * @param desc the application descriptor
- * @return true if the application is persistently locked.
- */
- public static boolean isLocked(ApplicationDescriptor desc) {
- synchronized (locks) {
- return locks.contains(desc.getApplicationId());
- }
- }
-
- /**
- * Used by {@link ApplicationDescriptor} to determine lock and unlock and application.
- * @param desc the application descriptor
- * @param locked the locked flag
- */
- public static void saveLock(ApplicationDescriptor desc, boolean locked) {
- synchronized (locks) {
- if (locked) {
- if (!locks.contains(desc.getApplicationId())) {
- locks.add(desc.getApplicationId());
- saveData(FILE_APPLOCKS);
- }
- } else if (locks.remove(desc.getApplicationId())) {
- saveData(FILE_APPLOCKS);
- }
- }
- }
-
- static void removeScheduledApp(EclipseScheduledApplication scheduledApp) {
- boolean removed;
- synchronized (scheduledApps) {
- removed = scheduledApps.remove(scheduledApp.getScheduleId()) != null;
- if (removed) {
- saveData(FILE_APPSCHEDULED);
- }
- }
- if (removed)
- synchronized (timerApps) {
- timerApps.remove(scheduledApp);
- }
- }
-
- /**
- * Used by {@link ScheduledApplication} to persistently schedule an application launch
- * @param descriptor
- * @param arguments
- * @param topic
- * @param eventFilter
- * @param recurring
- * @return the scheduled application
- * @throws InvalidSyntaxException
- * @throws ApplicationException
- */
- public static ScheduledApplication addScheduledApp(ApplicationDescriptor descriptor, String scheduleId, Map arguments, String topic, String eventFilter, boolean recurring) throws InvalidSyntaxException, ApplicationException {
- if (!scheduling && !checkSchedulingSupport())
- throw new ApplicationException(ApplicationException.APPLICATION_SCHEDULING_FAILED, "Cannot support scheduling without org.osgi.service.event package"); //$NON-NLS-1$
- // check the event filter for correct syntax
- context.createFilter(eventFilter);
- EclipseScheduledApplication result;
- synchronized (scheduledApps) {
- result = new EclipseScheduledApplication(context, getNextScheduledID(scheduleId), descriptor.getApplicationId(), arguments, topic, eventFilter, recurring);
- addScheduledApp(result);
- saveData(FILE_APPSCHEDULED);
- }
- return result;
- }
-
- // must call this method while holding the scheduledApps lock
- private static void addScheduledApp(EclipseScheduledApplication scheduledApp) {
- if (ScheduledApplication.TIMER_TOPIC.equals(scheduledApp.getTopic())) {
- synchronized (timerApps) {
- timerApps.add(scheduledApp);
- if (timerThread == null)
- startTimer();
- }
- }
- scheduledApps.put(scheduledApp.getScheduleId(), scheduledApp);
- Hashtable serviceProps = new Hashtable();
- if (scheduledApp.getTopic() != null)
- serviceProps.put(EventConstants.EVENT_TOPIC, new String[] {scheduledApp.getTopic()});
- if (scheduledApp.getEventFilter() != null)
- serviceProps.put(EventConstants.EVENT_FILTER, scheduledApp.getEventFilter());
- serviceProps.put(ScheduledApplication.SCHEDULE_ID, scheduledApp.getScheduleId());
- serviceProps.put(ScheduledApplication.APPLICATION_PID, scheduledApp.getAppPid());
- ServiceRegistration sr = context.registerService(new String[] {ScheduledApplication.class.getName(), EVENT_HANDLER}, scheduledApp, serviceProps);
- scheduledApp.setServiceRegistration(sr);
- }
-
- private static String getNextScheduledID(String scheduledId) throws ApplicationException {
- if (scheduledId != null) {
- if (scheduledApps.get(scheduledId) != null)
- throw new ApplicationException(ApplicationException.APPLICATION_DUPLICATE_SCHEDULE_ID, "Duplicate scheduled ID: " + scheduledId); //$NON-NLS-1$
- return scheduledId;
- }
- if (nextScheduledID == Integer.MAX_VALUE)
- nextScheduledID = 0;
- String result = new Integer(nextScheduledID++).toString();
- while (scheduledApps.get(result) != null && nextScheduledID < Integer.MAX_VALUE)
- result = new Integer(nextScheduledID++).toString();
- if (nextScheduledID == Integer.MAX_VALUE)
- throw new ApplicationException(ApplicationException.APPLICATION_DUPLICATE_SCHEDULE_ID, "Maximum number of scheduled applications reached"); //$NON-NLS-1$
- return result;
- }
-
- private static boolean checkSchedulingSupport() {
- // cannot support scheduling without the event admin package
- try {
- Class.forName(EVENT_HANDLER);
- scheduling = true;
- return true;
- } catch (ClassNotFoundException e) {
- scheduling = false;
- return false;
- }
- }
-
- private synchronized static boolean loadData(String fileName) {
- try {
- Location location = configLocation;
- if (location == null)
- return false;
- File theStorageDir = new File(location.getURL().getPath() + '/' + Activator.PI_APP);
- if (storageManager == null) {
- boolean readOnly = location.isReadOnly();
- storageManager = new StorageManager(theStorageDir, readOnly ? "none" : null, readOnly); //$NON-NLS-1$
- storageManager.open(!readOnly);
- }
- File dataFile = storageManager.lookup(fileName, false);
- if (dataFile == null || !dataFile.isFile()) {
- Location parent = location.getParentLocation();
- if (parent != null) {
- theStorageDir = new File(parent.getURL().getPath() + '/' + Activator.PI_APP);
- StorageManager tmp = new StorageManager(theStorageDir, "none", true); //$NON-NLS-1$
- tmp.open(false);
- dataFile = tmp.lookup(fileName, false);
- tmp.close();
- }
- }
- if (dataFile == null || !dataFile.isFile())
- return true;
- if (FILE_APPLOCKS.equals(fileName))
- loadLocks(dataFile);
- else if (FILE_APPSCHEDULED.equals(fileName))
- loadSchedules(dataFile);
- } catch (IOException e) {
- return false;
- }
- return true;
- }
-
- private static void loadLocks(File locksData) throws IOException {
- ObjectInputStream in = null;
- try {
- in = new ObjectInputStream(new FileInputStream(locksData));
- int dataVersion = in.readInt();
- if (dataVersion != DATA_VERSION)
- return;
- int numLocks = in.readInt();
- synchronized (locks) {
- for (int i = 0; i < numLocks; i++)
- locks.add(in.readUTF());
- }
- } finally {
- if (in != null)
- in.close();
- }
- }
-
- private static void loadSchedules(File schedulesData) throws IOException {
- ObjectInputStream in = null;
- try {
- in = new ObjectInputStream(new FileInputStream(schedulesData));
- int dataVersion = in.readInt();
- if (dataVersion != DATA_VERSION)
- return;
- int numScheds = in.readInt();
- for (int i = 0; i < numScheds; i++) {
- String id = readString(in, false);
- String appPid = readString(in, false);
- String topic = readString(in, false);
- String eventFilter = readString(in, false);
- boolean recurring = in.readBoolean();
- Map args = (Map) in.readObject();
- EclipseScheduledApplication schedApp = new EclipseScheduledApplication(context, id, appPid, args, topic, eventFilter, recurring);
- addScheduledApp(schedApp);
- }
- } catch (InvalidSyntaxException e) {
- throw new IOException(e.getMessage());
- } catch (NoClassDefFoundError e) {
- throw new IOException(e.getMessage());
- } catch (ClassNotFoundException e) {
- throw new IOException(e.getMessage());
- } finally {
- if (in != null)
- in.close();
- }
- }
-
- private synchronized static void saveData(String fileName) {
- if (storageManager == null || storageManager.isReadOnly())
- return;
- try {
- File data = storageManager.createTempFile(fileName);
- if (FILE_APPLOCKS.equals(fileName))
- saveLocks(data);
- else if (FILE_APPSCHEDULED.equals(fileName))
- saveSchedules(data);
- storageManager.lookup(fileName, true);
- storageManager.update(new String[] {fileName}, new String[] {data.getName()});
- } catch (IOException e) {
- Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.ERROR, 0, NLS.bind(Messages.persistence_error_saving, fileName), 0, e, null));
- }
- }
-
- // must call this while holding the locks lock
- private static void saveLocks(File locksData) throws IOException {
- ObjectOutputStream out = null;
- try {
- out = new ObjectOutputStream(new FileOutputStream(locksData));
- out.writeInt(DATA_VERSION);
- out.writeInt(locks.size());
- for (Iterator iterLocks = locks.iterator(); iterLocks.hasNext();)
- out.writeUTF((String) iterLocks.next());
- } finally {
- if (out != null)
- out.close();
- }
- }
-
- // must call this while holding the scheduledApps lock
- private static void saveSchedules(File schedulesData) throws IOException {
- ObjectOutputStream out = null;
- try {
- out = new ObjectOutputStream(new FileOutputStream(schedulesData));
- out.writeInt(DATA_VERSION);
- out.writeInt(scheduledApps.size());
- for (Iterator apps = scheduledApps.values().iterator(); apps.hasNext();) {
- EclipseScheduledApplication app = (EclipseScheduledApplication) apps.next();
- writeStringOrNull(out, app.getScheduleId());
- writeStringOrNull(out, app.getAppPid());
- writeStringOrNull(out, app.getTopic());
- writeStringOrNull(out, app.getEventFilter());
- out.writeBoolean(app.isRecurring());
- out.writeObject(app.getArguments());
- }
- } finally {
- if (out != null)
- out.close();
- }
- }
-
- private static void startTimer() {
- timerThread = new Thread(new AppTimer(), "app schedule timer"); //$NON-NLS-1$
- timerThread.start();
- }
-
- private static void stopTimer() {
- if (timerThread != null)
- timerThread.interrupt();
- timerThread = null;
- }
-
- static class AppTimer implements Runnable {
- public void run() {
- int lastMin = -1;
- while (!shutdown) {
- try {
- Thread.sleep(30000); // sleeping 30 secs instead of 60 to try to avoid skipping minutes
- Calendar cal = Calendar.getInstance();
- int minute = cal.get(Calendar.MINUTE);
- if (minute == lastMin)
- continue;
- lastMin = minute;
- Hashtable props = new Hashtable();
- props.put(ScheduledApplication.YEAR, new Integer(cal.get(Calendar.YEAR)));
- props.put(ScheduledApplication.MONTH, new Integer(cal.get(Calendar.MONTH)));
- props.put(ScheduledApplication.DAY_OF_MONTH, new Integer(cal.get(Calendar.DAY_OF_MONTH)));
- props.put(ScheduledApplication.DAY_OF_WEEK, new Integer(cal.get(Calendar.DAY_OF_WEEK)));
- props.put(ScheduledApplication.HOUR_OF_DAY, new Integer(cal.get(Calendar.HOUR_OF_DAY)));
- props.put(ScheduledApplication.MINUTE, new Integer(minute));
- Event timerEvent = new Event(ScheduledApplication.TIMER_TOPIC, (Dictionary) props);
- EclipseScheduledApplication[] apps = null;
- // poor mans implementation of dispatching events; the spec will not allow us to use event admin to dispatch the virtual timer events; boo!!
- synchronized (timerApps) {
- if (timerApps.size() == 0)
- continue;
- apps = (EclipseScheduledApplication[]) timerApps.toArray(new EclipseScheduledApplication[timerApps.size()]);
- }
- for (int i = 0; i < apps.length; i++) {
- try {
- String filterString = apps[i].getEventFilter();
- Filter filter = filterString == null ? null : FrameworkUtil.createFilter(filterString);
- if (filter == null || filter.match(props))
- apps[i].handleEvent(timerEvent);
- } catch (Throwable t) {
- String message = NLS.bind(Messages.scheduled_app_launch_error, apps[i].getAppPid());
- Activator.log(new FrameworkLogEntry(Activator.PI_APP, FrameworkLogEntry.WARNING, 0, message, 0, t, null));
- }
- }
- } catch (InterruptedException e) {
- // do nothing;
- }
- }
- }
- }
-
- private static String readString(ObjectInputStream in, boolean intern) throws IOException {
- byte type = in.readByte();
- if (type == NULL)
- return null;
- return intern ? in.readUTF().intern() : in.readUTF();
- }
-
- private static void writeStringOrNull(ObjectOutputStream out, String string) throws IOException {
- if (string == null)
- out.writeByte(NULL);
- else {
- out.writeByte(OBJECT);
- out.writeUTF(string);
- }
- }
-
- public Object addingService(ServiceReference reference) {
- if (configLocation != null)
- return null; // only care about one configuration
- configLocation = (Location) context.getService(reference);
- loadData(FILE_APPLOCKS);
- loadData(FILE_APPSCHEDULED);
- return configLocation;
- }
-
- public void modifiedService(ServiceReference reference, Object service) {
- // don't care
- }
-
- public void removedService(ServiceReference reference, Object service) {
- if (service == configLocation)
- configLocation = null;
- }
-}

Back to the top