View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.datamodel.ifs2;
20  
21  import java.io.IOException;
22  import java.io.UncheckedIOException;
23  import java.nio.file.Files;
24  import java.nio.file.Path;
25  import java.nio.file.attribute.BasicFileAttributes;
26  import java.util.stream.Stream;
27  
28  import org.jdom2.Element;
29  
30  /**
31   * Represents a directory stored in a file collection, which may contain other
32   * files and directories.
33   * 
34   * @author Frank Lützenkirchen
35   */
36  public class MCRDirectory extends MCRStoredNode {
37  
38      /**
39       * Create MCRDirectory representing an existing, already stored directory.
40       * 
41       * @param parent
42       *            the parent directory of this directory
43       * @param fo
44       *            the local directory in the store storing this directory
45       */
46      protected MCRDirectory(MCRDirectory parent, Path fo, Element data) {
47          super(parent, fo, data);
48      }
49  
50      /**
51       * Create a new MCRDirectory that does not exist yet
52       * 
53       * @param parent
54       *            the parent directory of this directory
55       * @param name
56       *            the name of the new subdirectory to create
57       */
58      protected MCRDirectory(MCRDirectory parent, String name) throws IOException {
59          super(parent, name, "dir");
60          Files.createDirectory(path);
61          getRoot().saveAdditionalData();
62      }
63  
64      /**
65       * Creates a new subdirectory within this directory
66       * 
67       * @param name
68       *            the name of the new directory
69       */
70      public MCRDirectory createDir(String name) throws IOException {
71          return new MCRDirectory(this, name);
72      }
73  
74      /**
75       * Creates a new file within this directory
76       * 
77       * @param name
78       *            the name of the new file
79       */
80      public MCRFile createFile(String name) throws IOException {
81          return new MCRFile(this, name);
82      }
83  
84      @SuppressWarnings("unchecked")
85      private Element getChildData(String name) {
86          for (Element child : readData(Element::getChildren)) {
87              if (name.equals(child.getAttributeValue("name"))) {
88                  return child;
89              }
90          }
91  
92          Element childData = new Element("node");
93          childData.setAttribute("name", name);
94          writeData(e -> e.addContent(childData));
95          return childData;
96      }
97  
98      /**
99       * Returns the MCRFile or MCRDirectory that is represented by the given
100      * FileObject, which is a direct child of the directory FileObject this
101      * MCRDirectory is stored in.
102      * 
103      * @return an MCRFile or MCRDirectory child
104      */
105     @Override
106     protected MCRStoredNode buildChildNode(Path fo) {
107         if (fo == null) {
108             return null;
109         }
110         if (!this.path.equals(fo.getParent())) {
111             throw new IllegalArgumentException(fo + " is not a direct child of " + this.path + ".");
112         }
113         BasicFileAttributes attrs;
114         try {
115             attrs = Files.readAttributes(fo, BasicFileAttributes.class);
116         } catch (IOException e) {
117             //does not exist
118             return null;
119         }
120 
121         Element childData = getChildData(fo.getFileName().toString());
122         if (attrs.isRegularFile()) {
123             return new MCRFile(this, fo, childData);
124         } else {
125             return new MCRDirectory(this, fo, childData);
126         }
127     }
128 
129     /**
130      * Repairs additional metadata of this directory and all its children
131      */
132     @Override
133     @SuppressWarnings("unchecked")
134     void repairMetadata() throws IOException {
135         writeData(e -> {
136             e.setName("dir");
137             e.setAttribute("name", getName());
138 
139             for (Element childEntry : e.getChildren()) {
140                 childEntry.setName("node");
141             }
142         });
143 
144         try (Stream<MCRNode> streamMCRNode = getChildren()) {
145             streamMCRNode.filter(MCRStoredNode.class::isInstance)
146                 .map(MCRStoredNode.class::cast)
147                 .sequential()
148                 .forEach(mcrStoredNode -> {
149                     try {
150                         mcrStoredNode.repairMetadata();
151                     } catch (IOException e) {
152                         throw new UncheckedIOException(e);
153                     }
154                 });
155         } catch (UncheckedIOException e) {
156             throw e.getCause();
157         }
158 
159         writeData(e -> e.removeChildren("node"));
160     }
161 }