001: package ru.emdev.EmForge.wiki.providers.mapprovider;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.ByteArrayOutputStream;
005: import java.io.IOException;
006: import java.io.InputStream;
007: import java.util.ArrayList;
008: import java.util.Collection;
009: import java.util.Date;
010: import java.util.HashMap;
011: import java.util.Iterator;
012: import java.util.List;
013: import java.util.Map;
014: import java.util.Properties;
015: import java.util.Set;
016:
017: import org.apache.commons.logging.Log;
018: import org.apache.commons.logging.LogFactory;
019:
020: import com.ecyrd.jspwiki.FileUtil;
021: import com.ecyrd.jspwiki.NoRequiredPropertyException;
022: import com.ecyrd.jspwiki.QueryItem;
023: import com.ecyrd.jspwiki.WikiEngine;
024: import com.ecyrd.jspwiki.WikiPage;
025: import com.ecyrd.jspwiki.attachment.Attachment;
026: import com.ecyrd.jspwiki.providers.ProviderException;
027: import com.ecyrd.jspwiki.providers.WikiAttachmentProvider;
028: import com.ecyrd.jspwiki.providers.WikiPageProvider;
029:
030: /** Memory Based Attachment provider
031: *
032: * This class is used for testing then Subversion is not available.
033: * Attachments are being saved in the memory.
034:
035: * @author spopov
036: *
037: */
038: public class MapAttachmentProvider implements WikiAttachmentProvider {
039: protected final Log logger = LogFactory.getLog(getClass());
040:
041: private WikiEngine m_engine;
042: private Map<String, Map<String, Map<Attachment, byte[]>>> m_attachmentMap = null; //<page_name, <attach_name, <attachment, content>>>
043:
044: public MapAttachmentProvider() {
045: m_attachmentMap = new HashMap<String, Map<String, Map<Attachment, byte[]>>>();
046: }
047:
048: public void putAttachmentData(Attachment i_att, InputStream i_data)
049: throws ProviderException, IOException {
050:
051: ByteArrayOutputStream out = new ByteArrayOutputStream();
052: Map<String, Map<Attachment, byte[]>> attachments = null;
053: Map<Attachment, byte[]> versAttachments = null;
054: // copy InputStream i_data to OutputStream out
055: FileUtil.copyContents(i_data, out);
056:
057: if (m_attachmentMap.containsKey(i_att.getParentName())) {
058: // page is exists: to get attachments with all version for this page
059:
060: attachments = m_attachmentMap.get(i_att.getParentName());
061: if (attachments.containsKey(i_att.getFileName())) {
062: // attachment is exists on the page: set new version attachment
063:
064: versAttachments = attachments.get(i_att.getFileName());
065: i_att.setVersion(versAttachments.size() + 1);
066:
067: } else {
068: versAttachments = new HashMap<Attachment, byte[]>();
069: i_att.setVersion(1);
070: }
071:
072: } else {
073: versAttachments = new HashMap<Attachment, byte[]>();
074: attachments = new HashMap<String, Map<Attachment, byte[]>>();
075: i_att.setVersion(1);
076: }
077:
078: // to work correctly and correctly display information we should set last modified date and size
079: i_att.setLastModified(new Date());
080: i_att.setSize(out.size());
081:
082: versAttachments.put((Attachment) i_att.clone(), out
083: .toByteArray());
084: attachments.put(i_att.getFileName(), versAttachments);
085: m_attachmentMap.put(i_att.getParentName(), attachments);
086: }
087:
088: public InputStream getAttachmentData(Attachment i_att)
089: throws ProviderException, IOException {
090:
091: byte[] data = null;
092: Map<String, Map<Attachment, byte[]>> attachments = m_attachmentMap
093: .get(i_att.getParentName());
094:
095: if (attachments != null) {
096: Map<Attachment, byte[]> versAttachments = attachments
097: .get(i_att.getFileName());
098: if (versAttachments != null) {
099: data = versAttachments.get(getAttachment(
100: versAttachments.keySet(), i_att.getVersion()));
101: }
102: }
103:
104: return new ByteArrayInputStream(data);
105: }
106:
107: /**
108: * @breaf return attachment with needed version; i_version = -1 - return the last version
109: * @param i_attachments
110: * @param i_version
111: * @return attachment with a version i_version
112: * @author spopov
113: */
114: private Attachment getAttachment(Collection i_attachments,
115: long i_version) {
116:
117: Attachment result = null;
118: long maxVersion = 1;
119: Iterator iterator = i_attachments.iterator();
120:
121: while (iterator.hasNext()) {
122: Attachment attachment = (Attachment) iterator.next();
123: long version = attachment.getVersion();
124: if (i_version == WikiPageProvider.LATEST_VERSION
125: && version >= maxVersion) {
126: // finding the last version
127: result = attachment;
128: maxVersion = version;
129: continue;
130: } else if (version == i_version) {
131: // finding requesting version
132: result = attachment;
133: }
134: }
135: return result;
136: }
137:
138: public Collection listAttachments(WikiPage i_page)
139: throws ProviderException {
140:
141: Map<String, Map<Attachment, byte[]>> attachments = null;
142: ArrayList<Attachment> result = new ArrayList<Attachment>();
143:
144: if (m_attachmentMap.containsKey(i_page.getName())) {
145: // on the page there are attachments
146: attachments = m_attachmentMap.get(i_page.getName());
147: if (attachments != null) {
148: // there are the versions attachments : select all attachments' keys with latest versions
149: Iterator iterator = attachments.keySet().iterator();
150: while (iterator.hasNext()) {
151: String keyAttachment = (String) iterator.next();
152: Set<Attachment> keyVersAttachments = attachments
153: .get(keyAttachment).keySet();
154: // add to list attachments with latest versions
155: result.add(getAttachment(keyVersAttachments,
156: WikiPageProvider.LATEST_VERSION));
157: }
158: }
159: }
160:
161: return result;
162: }
163:
164: public void initialize(WikiEngine engine, Properties properties)
165: throws NoRequiredPropertyException, IOException {
166: m_engine = engine;
167: }
168:
169: public void deleteAttachment(Attachment i_att)
170: throws ProviderException {
171:
172: Map<String, Map<Attachment, byte[]>> attachments = m_attachmentMap
173: .get(i_att.getParentName());
174: if (attachments != null) {
175: attachments.remove(i_att.getFileName());
176: }
177: }
178:
179: public void deleteVersion(Attachment i_att)
180: throws ProviderException {
181:
182: Map<String, Map<Attachment, byte[]>> attachments = m_attachmentMap
183: .get(i_att.getParentName());
184:
185: if (attachments != null) {
186: // get versions of the attachment
187: Map<Attachment, byte[]> versAttachments = attachments
188: .get(i_att.getFileName());
189: if (versAttachments != null) {
190: versAttachments.remove(i_att);
191: }
192: }
193: }
194:
195: public Collection findAttachments(QueryItem[] query) {
196: // TODO Auto-generated method stub
197: return null;
198: }
199:
200: public Attachment getAttachmentInfo(WikiPage i_page, String i_name,
201: int i_version) throws ProviderException {
202:
203: Attachment result = null;
204: Map<String, Map<Attachment, byte[]>> attachments = m_attachmentMap
205: .get(i_page.getName());
206:
207: if (attachments != null) {
208: // get all versions of attachment
209: Map<Attachment, byte[]> versAttachments = attachments
210: .get(i_name);
211: if (versAttachments != null) {
212: result = getAttachment(versAttachments.keySet(),
213: i_version);
214: }
215: }
216: return result;
217: }
218:
219: public List getVersionHistory(Attachment i_att) {
220:
221: ArrayList<Object> result = new ArrayList<Object>();
222: Map<String, Map<Attachment, byte[]>> attachments = m_attachmentMap
223: .get(i_att.getParentName());
224:
225: Iterator iterator = attachments.get(i_att.getFileName())
226: .keySet().iterator();
227: while (iterator.hasNext()) {
228: result.add(iterator.next());
229: }
230: return result;
231: }
232:
233: public List listAllChanged(Date timestamp) throws ProviderException {
234: // this method is currently implemented only for Date == 0L
235: if (timestamp.equals(new Date(0L))) {
236: ArrayList<Attachment> result = new ArrayList<Attachment>();
237:
238: // return all attachments
239: for (String page : m_attachmentMap.keySet()) {
240: result.add(getAttachment(m_attachmentMap.get(page)
241: .keySet(), WikiPageProvider.LATEST_VERSION));
242: }
243:
244: return result;
245: } else {
246: return new ArrayList();
247: }
248: }
249:
250: @SuppressWarnings("unchecked")
251: public void moveAttachmentsForPage(String i_oldParent,
252: String i_newParent) throws ProviderException {
253:
254: if (m_attachmentMap.containsKey(i_oldParent)) {
255: // get all versions of attachments of oldParent page
256: Collection<Attachment> attachs = listAttachments(new WikiPage(
257: m_engine, i_oldParent));
258: for (Attachment att : attachs) {
259: Collection<Attachment> verattachs = getVersionHistory(att);
260: for (Attachment oldatt : verattachs) {
261:
262: Attachment newatt = new Attachment(m_engine,
263: i_newParent, oldatt.getFileName());
264: newatt.setAuthor(oldatt.getAuthor());
265: newatt.setLastModified(oldatt.getLastModified());
266: newatt.setSize(oldatt.getSize());
267: newatt.setVersion(oldatt.getVersion());
268:
269: try {
270: InputStream data = getAttachmentData(oldatt);
271: putAttachmentData(newatt, data);
272: } catch (IOException e) {
273: e.printStackTrace();
274: }
275: }
276: }
277: m_attachmentMap.remove(i_oldParent);
278: }
279: }
280:
281: public String getProviderInfo() {
282: // TODO Auto-generated method stub
283: return "Memory Attachment Provider";
284: }
285: }
|