add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / store / FileSwitchDirectory.java
1 package org.apache.lucene.store;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.HashSet;
28
29 /**
30  * Expert: A Directory instance that switches files between
31  * two other Directory instances.
32
33  * <p>Files with the specified extensions are placed in the
34  * primary directory; others are placed in the secondary
35  * directory.  The provided Set must not change once passed
36  * to this class, and must allow multiple threads to call
37  * contains at once.</p>
38  *
39  * @lucene.experimental
40  */
41
42 public class FileSwitchDirectory extends Directory {
43   private final Directory secondaryDir;
44   private final Directory primaryDir;
45   private final Set<String> primaryExtensions;
46   private boolean doClose;
47
48   public FileSwitchDirectory(Set<String> primaryExtensions, Directory primaryDir, Directory secondaryDir, boolean doClose) {
49     this.primaryExtensions = primaryExtensions;
50     this.primaryDir = primaryDir;
51     this.secondaryDir = secondaryDir;
52     this.doClose = doClose;
53     this.lockFactory = primaryDir.getLockFactory();
54   }
55
56   /** Return the primary directory */
57   public Directory getPrimaryDir() {
58     return primaryDir;
59   }
60   
61   /** Return the secondary directory */
62   public Directory getSecondaryDir() {
63     return secondaryDir;
64   }
65   
66   @Override
67   public void close() throws IOException {
68     if (doClose) {
69       try {
70         secondaryDir.close();
71       } finally { 
72         primaryDir.close();
73       }
74       doClose = false;
75     }
76   }
77   
78   @Override
79   public String[] listAll() throws IOException {
80     Set<String> files = new HashSet<String>();
81     // LUCENE-3380: either or both of our dirs could be FSDirs,
82     // but if one underlying delegate is an FSDir and mkdirs() has not
83     // yet been called, because so far everything is written to the other,
84     // in this case, we don't want to throw a NoSuchDirectoryException
85     NoSuchDirectoryException exc = null;
86     try {
87       for(String f : primaryDir.listAll()) {
88         files.add(f);
89       }
90     } catch (NoSuchDirectoryException e) {
91       exc = e;
92     }
93     try {
94       for(String f : secondaryDir.listAll()) {
95         files.add(f);
96       }
97     } catch (NoSuchDirectoryException e) {
98       // we got NoSuchDirectoryException from both dirs
99       // rethrow the first.
100       if (exc != null) {
101         throw exc;
102       }
103       // we got NoSuchDirectoryException from the secondary,
104       // and the primary is empty.
105       if (files.isEmpty()) {
106         throw e;
107       }
108     }
109     // we got NoSuchDirectoryException from the primary,
110     // and the secondary is empty.
111     if (exc != null && files.isEmpty()) {
112       throw exc;
113     }
114     return files.toArray(new String[files.size()]);
115   }
116
117   /** Utility method to return a file's extension. */
118   public static String getExtension(String name) {
119     int i = name.lastIndexOf('.');
120     if (i == -1) {
121       return "";
122     }
123     return name.substring(i+1, name.length());
124   }
125
126   private Directory getDirectory(String name) {
127     String ext = getExtension(name);
128     if (primaryExtensions.contains(ext)) {
129       return primaryDir;
130     } else {
131       return secondaryDir;
132     }
133   }
134
135   @Override
136   public boolean fileExists(String name) throws IOException {
137     return getDirectory(name).fileExists(name);
138   }
139
140   @Override
141   public long fileModified(String name) throws IOException {
142     return getDirectory(name).fileModified(name);
143   }
144
145   @Deprecated
146   @Override
147   /*  @deprecated Lucene never uses this API; it will be
148    *  removed in 4.0. */
149   public void touchFile(String name) throws IOException {
150     getDirectory(name).touchFile(name);
151   }
152
153   @Override
154   public void deleteFile(String name) throws IOException {
155     getDirectory(name).deleteFile(name);
156   }
157
158   @Override
159   public long fileLength(String name) throws IOException {
160     return getDirectory(name).fileLength(name);
161   }
162
163   @Override
164   public IndexOutput createOutput(String name) throws IOException {
165     return getDirectory(name).createOutput(name);
166   }
167
168   @Deprecated
169   @Override
170   public void sync(String name) throws IOException {
171     sync(Collections.singleton(name));
172   }
173
174   @Override
175   public void sync(Collection<String> names) throws IOException {
176     List<String> primaryNames = new ArrayList<String>();
177     List<String> secondaryNames = new ArrayList<String>();
178
179     for (String name : names)
180       if (primaryExtensions.contains(getExtension(name)))
181         primaryNames.add(name);
182       else
183         secondaryNames.add(name);
184
185     primaryDir.sync(primaryNames);
186     secondaryDir.sync(secondaryNames);
187   }
188
189   @Override
190   public IndexInput openInput(String name) throws IOException {
191     return getDirectory(name).openInput(name);
192   }
193 }