001 /*
002 * $Revision: 15002 $
003 * $Date: 2009-03-25 09:36:28 +0100 (Wed, 25 Mar 2009) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.datamodel.ifs2;
025
026 import java.io.File;
027
028 import org.apache.commons.vfs.FileObject;
029 import org.apache.commons.vfs.provider.local.LocalFile;
030 import org.apache.log4j.Logger;
031 import org.jdom.Element;
032 import org.mycore.common.MCRUtils;
033
034 /**
035 * Represents a file stored in a file collection. This is a file that is
036 * imported from outside the system, and may be updated and modified afterwards.
037 *
038 * @author Frank Lützenkirchen
039 *
040 */
041 public class MCRFile extends MCRStoredNode {
042
043 private final static Logger LOGGER = Logger.getLogger(MCRFile.class);
044
045 /**
046 * The md5 checksum of the empty file
047 */
048 public final static String MD5_OF_EMPTY_FILE = "d41d8cd98f00b204e9800998ecf8427e";
049
050 /**
051 * Returns a MCRFile object representing an existing file already stored in
052 * the store.
053 *
054 * @param parent
055 * the parent directory containing this file
056 * @param fo
057 * the file in the local underlying filesystem storing this file
058 */
059 protected MCRFile(MCRDirectory parent, FileObject fo, Element data) throws Exception {
060 super(parent, fo, data);
061 }
062
063 /**
064 * Creates a new MCRFile that does not exist yet
065 *
066 * @param parent
067 * the parent directory
068 * @param name
069 * the file name
070 */
071 protected MCRFile(MCRDirectory parent, String name) throws Exception {
072 super(parent, name, "file");
073 fo.createFile();
074 data.setAttribute("md5", MCRFile.MD5_OF_EMPTY_FILE);
075 getRoot().saveAdditionalData();
076 }
077
078 /**
079 * Returns a MCRVirtualNode contained in this file as a child. A file that
080 * is a container, like zip or tar, may contain other files as children.
081 */
082 protected MCRVirtualNode buildChildNode(FileObject fo) throws Exception {
083 return new MCRVirtualNode(this, fo);
084 }
085
086 /**
087 * Returns the md5 checksum of the file's content.
088 *
089 * @return the md5 checksum of the file's content.
090 */
091 public String getMD5() {
092 return data.getAttributeValue("md5");
093 }
094
095 /**
096 * Returns the file name extension, which is the part after the last dot in
097 * the filename.
098 *
099 * @return the file extension, or the empty string if the file name does not
100 * have an extension
101 */
102 public String getExtension() {
103 String name = this.getName();
104 int pos = name.lastIndexOf(".");
105 return (pos == -1 ? "" : name.substring(pos + 1));
106 }
107
108 /**
109 * Sets the content of this file.
110 *
111 * @param content
112 * the content to be read
113 * @return the MD5 checksum of the stored content
114 */
115 public String setContent(MCRContent source) throws Exception {
116 MCRContentInputStream cis = source.getContentInputStream();
117 source.sendTo(fo);
118 String md5 = cis.getMD5String();
119 data.setAttribute("md5", md5);
120 getRoot().saveAdditionalData();
121 return md5;
122 }
123
124 /**
125 * Returns the local java.io.File representing this stored file. Be careful
126 * to use this only for reading data, do never modify directly!
127 *
128 * @return the file in the local filesystem representing this file
129 */
130 public File getLocalFile() throws Exception {
131 if (fo instanceof LocalFile)
132 return new File(fo.getURL().getPath());
133 else
134 return null;
135 }
136
137 /**
138 * Repairs additional metadata of this file and all its children
139 */
140 void repairMetadata() throws Exception {
141 data.setName("file");
142 data.setAttribute("name", getName());
143 data.removeChildren("file");
144 data.removeChildren("directory");
145 MCRContentInputStream cis = getContent().getContentInputStream();
146 MCRUtils.copyStream(cis, null);
147 cis.close();
148 String md5 = cis.getMD5String();
149 if (!md5.equals(data.getAttributeValue("md5"))) {
150 LOGGER.warn("Fixed MD5 of " + getPath() + " to " + md5);
151 data.setAttribute("md5", md5);
152 }
153 }
154 }