/* * Copyright (c) 2004-2011 Marco Maccaferri 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: * Marco Maccaferri - initial API and implementation */ package org.eclipsetrader.repository.local.internal.stores; import java.io.File; import java.io.FileWriter; import java.net.URI; import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipsetrader.core.feed.IHistory; import org.eclipsetrader.core.feed.IOHLC; import org.eclipsetrader.core.feed.TimeSpan; import org.eclipsetrader.core.instruments.ISecurity; import org.eclipsetrader.core.repositories.IPropertyConstants; import org.eclipsetrader.core.repositories.IRepository; import org.eclipsetrader.core.repositories.IStore; import org.eclipsetrader.core.repositories.IStoreProperties; import org.eclipsetrader.core.repositories.StoreProperties; import org.eclipsetrader.repository.local.LocalRepository; import org.eclipsetrader.repository.local.internal.Activator; import org.eclipsetrader.repository.local.internal.types.HistoryDayType; import org.eclipsetrader.repository.local.internal.types.HistoryType; public class IntradayHistoryStore implements IStore { private Integer id; private ISecurity security; private Date date; private Map<TimeSpan, IOHLC[]> bars = new HashMap<TimeSpan, IOHLC[]>(); private HistoryDayType dayType; protected IntradayHistoryStore() { } public IntradayHistoryStore(Integer id, ISecurity security, Date date) { this.id = id; this.security = security; this.date = date; } public IntradayHistoryStore(Integer id, ISecurity security, HistoryDayType dayType) { this.id = id; this.security = security; this.date = dayType.getDate(); this.dayType = dayType; for (HistoryType type : dayType.getPeriods()) { List<IOHLC> l = type.getData(); this.bars.put(type.getPeriod(), l.toArray(new IOHLC[l.size()])); } } /* (non-Javadoc) * @see org.eclipsetrader.core.repositories.IStore#createChild() */ @Override public IStore createChild() { return null; } /* (non-Javadoc) * @see org.eclipsetrader.core.repositories.IStore#delete(org.eclipse.core.runtime.IProgressMonitor) */ @Override public void delete(IProgressMonitor monitor) throws CoreException { File file = getFile(); if (file.exists()) { file.delete(); } } /* (non-Javadoc) * @see org.eclipsetrader.core.repositories.IStore#fetchChilds(org.eclipse.core.runtime.IProgressMonitor) */ @Override public IStore[] fetchChilds(IProgressMonitor monitor) { return null; } protected void loadHistoryDayType() { if (dayType == null) { File file = getFile(); if (file.exists()) { dayType = (HistoryDayType) unmarshal(HistoryDayType.class, file); } if (dayType == null) { dayType = new HistoryDayType(security, date); } for (HistoryType type : dayType.getPeriods()) { if (!bars.containsKey(type.getPeriod())) { List<IOHLC> l = type.getData(); bars.put(type.getPeriod(), l.toArray(new IOHLC[l.size()])); } } } } /* (non-Javadoc) * @see org.eclipsetrader.core.repositories.IStore#fetchProperties(org.eclipse.core.runtime.IProgressMonitor) */ @Override public IStoreProperties fetchProperties(IProgressMonitor monitor) { StoreProperties properties = new StoreProperties() { @Override public String[] getPropertyNames() { loadHistoryDayType(); Set<String> s = new HashSet<String>(Arrays.asList(super.getPropertyNames())); for (HistoryType type : dayType.getPeriods()) { s.add(type.getPeriod().toString()); } return s.toArray(new String[s.size()]); } @Override public Object getProperty(String name) { Object o = super.getProperty(name); if (o != null) { return o; } TimeSpan timeSpan = TimeSpan.fromString(name); if (timeSpan != null) { loadHistoryDayType(); return bars.get(timeSpan); } return null; } }; properties.setProperty(IPropertyConstants.OBJECT_TYPE, IHistory.class.getName()); properties.setProperty(IPropertyConstants.SECURITY, security); properties.setProperty(IPropertyConstants.BARS_DATE, date); return properties; } /* (non-Javadoc) * @see org.eclipsetrader.core.repositories.IStore#putProperties(org.eclipsetrader.core.repositories.IStoreProperties, org.eclipse.core.runtime.IProgressMonitor) */ @Override public void putProperties(IStoreProperties properties, IProgressMonitor monitor) { security = (ISecurity) properties.getProperty(IPropertyConstants.SECURITY); date = (Date) properties.getProperty(IPropertyConstants.BARS_DATE); loadHistoryDayType(); for (String name : properties.getPropertyNames()) { TimeSpan timeSpan = TimeSpan.fromString(name); if (timeSpan != null) { IOHLC[] ohlc = (IOHLC[]) properties.getProperty(name); bars.put(timeSpan, ohlc); dayType.addHistory(new HistoryType(security, ohlc, timeSpan)); } } File file = getFile(); if (bars.size() != 0) { marshal(dayType, HistoryDayType.class, file); } else { if (file.exists()) { file.delete(); } } } /* (non-Javadoc) * @see org.eclipsetrader.core.repositories.IStore#getRepository() */ @Override public IRepository getRepository() { return Activator.getDefault().getRepository(); } /* (non-Javadoc) * @see org.eclipsetrader.core.repositories.IStore#toURI() */ @Override public URI toURI() { try { return new URI(LocalRepository.URI_SCHEMA, LocalRepository.URI_SECURITY_HISTORY_PART + "/" + new SimpleDateFormat("yyyyMMdd").format(date), String.valueOf(id)); } catch (URISyntaxException e) { } return null; } @SuppressWarnings("unchecked") protected Object unmarshal(Class clazz, File file) { try { if (file.exists()) { JAXBContext jaxbContext = JAXBContext.newInstance(clazz); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); unmarshaller.setEventHandler(new ValidationEventHandler() { @Override public boolean handleEvent(ValidationEvent event) { Status status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, 0, "Error validating XML: " + event.getMessage(), null); //$NON-NLS-1$ Activator.log(status); return true; } }); return unmarshaller.unmarshal(file); } } catch (Exception e) { Status status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, 0, "Error loading history", null); //$NON-NLS-1$ Activator.log(status); } return null; } @SuppressWarnings("unchecked") protected void marshal(Object object, Class clazz, File file) { try { if (file.exists()) { file.delete(); } JAXBContext jaxbContext = JAXBContext.newInstance(clazz); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setEventHandler(new ValidationEventHandler() { @Override public boolean handleEvent(ValidationEvent event) { return true; } }); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setProperty(Marshaller.JAXB_ENCODING, System.getProperty("file.encoding")); //$NON-NLS-1$ marshaller.marshal(object, new FileWriter(file)); } catch (Exception e) { e.printStackTrace(); } } protected File getFile() { IPath path = LocalRepository.getInstance().getLocation().append(LocalRepository.SECURITIES_HISTORY_FILE).append("." + String.valueOf(id)); path.toFile().mkdirs(); return path.append(new SimpleDateFormat("yyyyMMdd").format(date) + ".xml").toFile(); } }