1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.team.examples.filesystem.subscriber;
15 
16 import java.io.BufferedInputStream;
17 import java.io.FileInputStream;
18 import java.io.FileNotFoundException;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.Date;
22 
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Status;
26 import org.eclipse.team.core.TeamException;
27 import org.eclipse.team.core.variants.CachedResourceVariant;
28 import org.eclipse.team.examples.filesystem.FileSystemPlugin;
29 
30 /**
31  * A file system resource variant. Although not strictly necessary, this
32  * class extends <code>CachedResourceVariant</code> which will
33  * cache the contents of the resource variant.
34  */
35 public class FileSystemResourceVariant extends CachedResourceVariant {
36 
37 	private java.io.File ioFile;
38 	private byte[] bytes;
39 
40 	/**
41 	 * Create a resource variant for the given file. The bytes will
42 	 * be calculated when they are accessed.
43 	 * @param file the file
44 	 */
FileSystemResourceVariant(java.io.File file)45 	public FileSystemResourceVariant(java.io.File file) {
46 		this.ioFile = file;
47 	}
48 
49 	/**
50 	 * Create a resource variant for the given file and sync bytes.
51 	 * @param file the file
52 	 * @param bytes the timestamp bytes
53 	 */
FileSystemResourceVariant(java.io.File file, byte[] bytes)54 	public FileSystemResourceVariant(java.io.File file, byte[] bytes) {
55 		this.ioFile = file;
56 		this.bytes = bytes;
57 	}
58 
59 	@Override
fetchContents(IProgressMonitor monitor)60 	protected void fetchContents(IProgressMonitor monitor) throws TeamException {
61 		setContents(getContents(), monitor);
62 	}
63 
64 	@Override
getCachePath()65 	protected String getCachePath() {
66 		// append the timestamp to the file path to give each variant a unique path
67 		return getFilePath() + " " + ioFile.lastModified(); //$NON-NLS-1$
68 	}
69 
getFilePath()70 	private String getFilePath() {
71 		try {
72 			return ioFile.getCanonicalPath();
73 		} catch (IOException e) {
74 			// Failed for some reason. Try the absolute path.
75 			FileSystemPlugin.log(new Status(IStatus.ERROR, FileSystemPlugin.ID, 0,
76 					"Failed to obtain canonical path for " + ioFile.getAbsolutePath(), e)); //$NON-NLS-1$
77 			return ioFile.getAbsolutePath();
78 		}
79 	}
80 
81 	@Override
getCacheId()82 	protected String getCacheId() {
83 		return FileSystemPlugin.ID;
84 	}
85 
86 	@Override
getName()87 	public String getName() {
88 		return ioFile.getName();
89 	}
90 
91 	@Override
isContainer()92 	public boolean isContainer() {
93 		return ioFile.isDirectory();
94 	}
95 
96 	@Override
getContentIdentifier()97 	public String getContentIdentifier() {
98 		// Use the modification timestamp as the content identifier
99 		return new Date(ioFile.lastModified()).toString();
100 	}
101 
102 	@Override
asBytes()103 	public byte[] asBytes() {
104 		if (bytes == null) {
105 			// For simplicity, convert the timestamp to it's string representation.
106 			// A more optimal storage format would be the 8 bytes that make up the long.
107 			bytes = Long.toString(ioFile.lastModified()).getBytes();
108 		}
109 		return bytes;
110 	}
111 
112 	/**
113 	 * Return the files contained by the file of this resource variant.
114 	 * @return the files contained by the file of this resource variant.
115 	 */
members()116 	public FileSystemResourceVariant[] members() {
117 		if (isContainer()) {
118 			java.io.File[] members = ioFile.listFiles();
119 			if (members == null) {
120 				members = new java.io.File[0];
121 			}
122 			FileSystemResourceVariant[] result = new FileSystemResourceVariant[members.length];
123 			for (int i = 0; i < members.length; i++) {
124 				result[i] = new FileSystemResourceVariant(members[i]);
125 			}
126 			return result;
127 		}
128 		return new FileSystemResourceVariant[0];
129 	}
130 
131 	/**
132 	 * @return
133 	 */
getContents()134 	public InputStream getContents() throws TeamException {
135 		try {
136 			return new BufferedInputStream(new FileInputStream(ioFile));
137 		} catch (FileNotFoundException e) {
138 			throw new TeamException("Failed to fetch contents for " + getFilePath(), e); //$NON-NLS-1$
139 		}
140 	}
141 
getFile()142 	public java.io.File getFile(){
143 		return ioFile;
144 	}
145 }
146