001/*- 002 ******************************************************************************* 003 * Copyright (c) 2011, 2016 Diamond Light Source Ltd. 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Peter Chang - initial API and implementation and/or initial documentation 011 *******************************************************************************/ 012 013package org.eclipse.january.metadata; 014 015import java.io.ByteArrayOutputStream; 016import java.io.Serializable; 017import java.util.Collection; 018import java.util.Collections; 019import java.util.HashMap; 020import java.util.LinkedHashMap; 021import java.util.Map; 022import java.util.Map.Entry; 023 024import org.apache.commons.lang.SerializationUtils; 025import org.eclipse.january.MetadataException; 026import org.eclipse.january.dataset.ShapeUtils; 027 028 029/** 030 * Basic implementation of metadata 031 */ 032public class Metadata implements IMetadata { 033 private static final long serialVersionUID = IMetadata.serialVersionUID; 034 035 private Map<String, ? extends Serializable> metadata; 036 // NOTE shapes is LinkedHashMap here because the names collection 037 // maintained order. Now that we do not need this collection but if we 038 // do not keep the shapes in a LinkedHashMap, we lose order. 039 private Map<String,int[]> shapes = new LinkedHashMap<String,int[]>(7); 040 private Collection<Serializable> userObjects; 041 private String filePath; 042 043 044 public Metadata() { 045 } 046 047 public Metadata(Map<String, ? extends Serializable> metadata) { 048 initialize(metadata); 049 } 050 051 @Override 052 public void initialize(Map<String, ? extends Serializable> metadata) { 053 this.metadata = metadata; 054 } 055 056 @Override 057 public void addNames(Collection<String> names) { 058 if (names != null) { 059 for (String n : names) { 060 shapes.put(n, null); 061 } 062 } 063 } 064 065 /** 066 * Set metadata map 067 * @param metadata 068 */ 069 @Override 070 public void setMetadata(Map<String, ? extends Serializable> metadata) { 071 this.metadata = metadata; 072 } 073 074 /** 075 * Internal use only 076 * @return metadata map 077 */ 078 protected Map<String, ? extends Serializable> getInternalMetadata() { 079 return metadata; 080 } 081 082 /** 083 * Set user objects 084 * @param objects 085 */ 086 public void setUserObjects(Collection<Serializable> objects) { 087 userObjects = objects; 088 } 089 090 public void addDataInfo(String name, int... shape) { 091 shapes.put(name, shape); 092 } 093 094 @Override 095 public Collection<String> getDataNames() { 096 return Collections.unmodifiableCollection(shapes.keySet()); 097 } 098 099 @Override 100 public Map<String, int[]> getDataShapes() { 101 return Collections.unmodifiableMap(shapes); 102 } 103 104 @Override 105 public Map<String, Integer> getDataSizes() { 106 Map<String, Integer> sizes = new HashMap<String, Integer>(1); 107 for (Entry<String, int[]> e : shapes.entrySet()) { 108 int[] shape = e.getValue(); 109 if (shape != null && shape.length > 1) 110 sizes.put(e.getKey(), ShapeUtils.calcSize(shape)); 111 else 112 sizes.put(e.getKey(), null); 113 } 114 if (sizes.size() > 0) { 115 return Collections.unmodifiableMap(sizes); 116 } 117 return null; 118 } 119 120 @Override 121 public Serializable getMetaValue(String key) throws MetadataException { 122 return metadata == null ? null : metadata.get(key); 123 } 124 125 @SuppressWarnings("unchecked") 126 @Override 127 public Collection<String> getMetaNames() throws MetadataException { 128 return metadata == null ? (Collection<String>) Collections.EMPTY_SET : Collections.unmodifiableCollection(metadata.keySet()); 129 } 130 131 @Override 132 public Collection<Serializable> getUserObjects() { 133 return userObjects; 134 } 135 136 @Override 137 public IMetadata clone() { 138 Metadata c = null; 139 try { 140 c = (Metadata) super.clone(); 141 if (metadata != null) { 142 HashMap<String, Serializable> md = new HashMap<String, Serializable>(); 143 c.metadata = md; 144 ByteArrayOutputStream os = new ByteArrayOutputStream(512); 145 for (String k : metadata.keySet()) { 146 Serializable v = metadata.get(k); 147 if (v != null) { 148 SerializationUtils.serialize(v, os); 149 Serializable nv = (Serializable) SerializationUtils.deserialize(os.toByteArray()); 150 os.reset(); 151 md.put(k, nv); 152 } else { 153 md.put(k, null); 154 } 155 } 156 } 157 c.shapes = new HashMap<String, int[]>(1); 158 for (Entry<String, int[]> e : shapes.entrySet()) { 159 int[] s = e.getValue(); 160 c.shapes.put(e.getKey(), s == null ? null : s.clone()); 161 } 162 } catch (CloneNotSupportedException e) { 163 // Allowed for some objects not to be cloned. 164 } catch (Throwable e) { 165 if (e instanceof ClassNotFoundException) { 166 // Fix to http://jira.diamond.ac.uk/browse/SCI-1644 167 // Happens when cloning meta data with GridPreferences 168 } if (e instanceof RuntimeException ) { 169 throw (RuntimeException)e; 170 } 171 } 172 return c; 173 } 174 175 @Override 176 public String getFilePath() { 177 return filePath; 178 } 179 180 @Override 181 public void setFilePath(String filePath) { 182 this.filePath = filePath; 183 } 184}