Java tutorial
/******************************************************************************* * Copyright (c) 2004, 2009 Tasktop Technologies 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: * Tasktop Technologies - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.context.core; import java.io.File; import java.io.FileOutputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; import org.apache.commons.io.IOUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.context.core.IContextContributor; import org.eclipse.mylyn.context.core.IInteractionContext; import org.eclipse.mylyn.context.core.IInteractionContextScaling; /** * @author Mik Kersten * @author Jevgeni Holodkov */ public class InteractionContextExternalizer { public static final String ELMNT_INTERACTION_HISTORY_OLD = "interactionEvent"; //$NON-NLS-1$ public static final String ELMNT_INTERACTION_HISTORY = "InteractionHistory"; //$NON-NLS-1$ public static final String ATR_STRUCTURE_KIND = "StructureKind"; //$NON-NLS-1$ public static final String ATR_STRUCTURE_HANDLE = "StructureHandle"; //$NON-NLS-1$ public static final String ATR_START_DATE = "StartDate"; //$NON-NLS-1$ public static final String ATR_ORIGIN_ID = "OriginId"; //$NON-NLS-1$ public static final String ATR_NAVIGATION = "Navigation"; //$NON-NLS-1$ public static final String ATR_KIND = "Kind"; //$NON-NLS-1$ public static final String ATR_INTEREST = "Interest"; //$NON-NLS-1$ public static final String ATR_NUM_EVENTS = "NumEvents"; //$NON-NLS-1$ public static final String ATR_CREATION_COUNT = "CreationCount"; //$NON-NLS-1$ public static final String ATR_DELTA = "Delta"; //$NON-NLS-1$ public static final String ATR_END_DATE = "EndDate"; //$NON-NLS-1$ public static final String ATR_ID = "Id"; //$NON-NLS-1$ public static final String ATR_VERSION = "Version"; //$NON-NLS-1$ static final String DATE_FORMAT_STRING = "yyyy-MM-dd HH:mm:ss.S z"; //$NON-NLS-1$ static String getFirstContextHandle(File sourceFile) throws CoreException { try { ZipFile zipFile = new ZipFile(sourceFile); try { for (Enumeration<?> e = zipFile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); String name = entry.getName(); if (name.endsWith(InteractionContextManager.CONTEXT_FILE_EXTENSION_OLD)) { try { String decodedName = URLDecoder.decode(name, InteractionContextManager.CONTEXT_FILENAME_ENCODING); if (decodedName.length() > InteractionContextManager.CONTEXT_FILE_EXTENSION_OLD .length()) { return decodedName.substring(0, decodedName.length() - InteractionContextManager.CONTEXT_FILE_EXTENSION_OLD.length()); } } catch (IllegalArgumentException ignored) { // not a valid context entry } } } return null; } finally { zipFile.close(); } } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, ContextCorePlugin.ID_PLUGIN, "Could not get context handle from " + sourceFile, e)); //$NON-NLS-1$ } } public void writeContextToXml(IInteractionContext context, File file) throws IOException { writeContextToXml(context, file, new SaxContextWriter()); } /** * Public for testing. * * @throws IOException * if writing of context fails */ public void writeContextToXml(IInteractionContext context, File file, IInteractionContextWriter writer) throws IOException { if (context.getInteractionHistory().isEmpty()) { return; } FileOutputStream fileOutputStream = new FileOutputStream(file); try { ZipOutputStream outputStream = new ZipOutputStream(fileOutputStream); try { writeContext(context, outputStream, writer); } finally { outputStream.close(); } } finally { fileOutputStream.close(); } } public void writeContext(IInteractionContext context, ZipOutputStream outputStream) throws IOException { writeContext(context, outputStream, new SaxContextWriter()); } /** * For testing */ public void writeContext(IInteractionContext context, ZipOutputStream outputStream, IInteractionContextWriter writer) throws IOException { String handleIdentifier = context.getHandleIdentifier(); String encoded = URLEncoder.encode(handleIdentifier, InteractionContextManager.CONTEXT_FILENAME_ENCODING); ZipEntry zipEntry = new ZipEntry(encoded + InteractionContextManager.CONTEXT_FILE_EXTENSION_OLD); outputStream.putNextEntry(zipEntry); outputStream.setMethod(ZipOutputStream.DEFLATED); writer.setOutputStream(outputStream); writer.writeContextToStream(context); outputStream.flush(); outputStream.closeEntry(); addAdditionalInformation(context, outputStream); } private void addAdditionalInformation(final IInteractionContext context, final ZipOutputStream outputStream) throws IOException { for (final IContextContributor contributor : getContextContributor()) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log( new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, "Context contribution failed: " //$NON-NLS-1$ + contributor.getClass(), e)); } public void run() throws Exception { InputStream additionalContextInformation = contributor.getDataAsStream(context); if (additionalContextInformation != null) { try { String encoded = URLEncoder.encode(contributor.getIdentifier(), InteractionContextManager.CONTEXT_FILENAME_ENCODING); ZipEntry zipEntry = new ZipEntry(encoded); outputStream.putNextEntry(zipEntry); IOUtils.copy(additionalContextInformation, outputStream); outputStream.flush(); outputStream.closeEntry(); } finally { additionalContextInformation.close(); } } } }); } } public InputStream getAdditionalInformation(File file, String contributorIdentifier) throws IOException { if (!file.exists()) { return null; } final ZipFile zipFile = new ZipFile(file); ZipEntry entry = findFileInZip(zipFile, contributorIdentifier); if (entry == null) { return null; } return new FilterInputStream(zipFile.getInputStream(entry)) { @Override public void close() throws IOException { super.close(); zipFile.close(); } }; } private ZipEntry findFileInZip(ZipFile zipFile, String identifier) throws UnsupportedEncodingException { String encoded = URLEncoder.encode(identifier, InteractionContextManager.CONTEXT_FILENAME_ENCODING); for (Enumeration<?> e = zipFile.entries(); e.hasMoreElements();) { ZipEntry entry = (ZipEntry) e.nextElement(); if (entry.getName().equals(encoded)) { return entry; } } return null; } private List<IContextContributor> getContextContributor() { return ContextCorePlugin.getDefault().getContextContributor(); } public IInteractionContext readContextFromXml(String handleIdentifier, File fromFile, IInteractionContextScaling scaling) { return readContextFromXml(handleIdentifier, fromFile, new SaxContextReader(), scaling); } /** * Public for testing */ public IInteractionContext readContextFromXml(String handleIdentifier, File fromFile, IInteractionContextReader reader, IInteractionContextScaling scaling) { try { if (!fromFile.exists()) { return null; } else { if (reader instanceof SaxContextReader) { ((SaxContextReader) reader).setContextScaling(scaling); } InteractionContext context = reader.readContext(handleIdentifier, fromFile); if (context == null) { String firstHandle = getFirstContextHandle(fromFile); if (firstHandle != null && !firstHandle.equals(handleIdentifier)) { context = reader.readContext(firstHandle, fromFile); if (context != null) { context.setHandleIdentifier(handleIdentifier); } } } return context; } } catch (Exception e) { // TODO: propagate exception instead? StatusHandler.log(new Status(IStatus.ERROR, ContextCorePlugin.ID_PLUGIN, "Could not read: " //$NON-NLS-1$ + fromFile.getAbsolutePath(), e)); } return null; } }