Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * @(#)Partition.java 1.0 6/29/2001 | |
3 | * | |
4 | * Copyright (c) 2001 International Business Machines Corp. | |
5 | * All rights reserved. | |
6 | * | |
7 | * This software has been released under the terms of the IBM Public | |
8 | * License. For details, see the LICENSE file in the top-level source | |
9 | * directory or online at http://www.openafs.org/dl/license10.html | |
10 | * | |
11 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
12 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
13 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
14 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR | |
15 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
16 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
17 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
18 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
19 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
20 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
21 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
22 | */ | |
23 | ||
24 | package org.openafs.jafs; | |
25 | ||
26 | import java.io.Serializable; | |
27 | import java.util.ArrayList; | |
28 | ||
29 | /** | |
30 | * An abstract representation of an AFS partition. It holds information about | |
31 | * the partition, such as what its total space is. | |
32 | * <BR><BR> | |
33 | * | |
34 | * Constructing an instance of a <code>Partition</code> does not mean | |
35 | * an actual AFS partition is created on a server -- on the contrary, | |
36 | * a <code>Partition</code> object must be a representation of an already | |
37 | * existing AFS partition. There is no way to create a new AFS partition | |
38 | * through this API.<BR><BR> | |
39 | * | |
40 | * Each <code>Partition</code> object has its own individual set of | |
41 | * <code>Volume</code>s. This represents the properties and attributes | |
42 | * of an actual AFS cell.<BR><BR> | |
43 | * | |
44 | * <!--Example of how to use class--> | |
45 | * The following is a simple example of how to obtain and use a | |
46 | * <code>Partition</code> object. In this example, a list of the | |
47 | * <code>Partition</code> objects of a server are obtained, and the name | |
48 | * and number of volumes is printed out for each one.<BR><BR> | |
49 | * | |
50 | * <PRE> | |
51 | * import org.openafs.jafs.Cell; | |
52 | * import org.openafs.jafs.AFSException; | |
53 | * import org.openafs.jafs.Partition; | |
54 | * import org.openafs.jafs.Server; | |
55 | * ... | |
56 | * public class ... | |
57 | * { | |
58 | * ... | |
59 | * private Cell cell; | |
60 | * private Server server; | |
61 | * ... | |
62 | * public static void main(String[] args) throws Exception | |
63 | * { | |
64 | * String username = arg[0]; | |
65 | * String password = arg[1]; | |
66 | * String cellName = arg[2]; | |
67 | * String serverName = arg[3]; | |
68 | * | |
69 | * token = new Token(username, password, cellName); | |
70 | * cell = new Cell(token); | |
71 | * server = new Server(serverName, cell); | |
72 | * | |
73 | * System.out.println("Partitions in Server " + server.getName() + ":"); | |
74 | * Partition[] partitions = server.getPartitions(); | |
75 | * for (int i = 0; i < partitions.length; i++) { | |
76 | * System.out.print("Partition " + partitions[i].getName()); | |
77 | * System.out.print("hosts " + partitions[i].getVolumeCount()); | |
78 | * System.out.print("volumes.\n"); | |
79 | * } | |
80 | * } | |
81 | * ... | |
82 | * } | |
83 | * </PRE> | |
84 | * | |
85 | */ | |
86 | public class Partition implements Serializable, Comparable | |
87 | { | |
88 | protected Cell cell; | |
89 | protected Server server; | |
90 | ||
91 | /* Populated by native method */ | |
92 | protected String name; | |
93 | ||
94 | /* Populated by native method */ | |
95 | protected int id; | |
96 | ||
97 | /* Populated by native method */ | |
98 | protected String deviceName; | |
99 | ||
100 | /* Populated by native method */ | |
101 | protected int lockFileDescriptor; | |
102 | ||
103 | /* Populated by native method */ | |
104 | protected int totalSpace; | |
105 | ||
106 | /* Populated by native method */ | |
107 | protected int totalFreeSpace; | |
108 | ||
109 | protected int totalQuota; | |
110 | ||
111 | protected ArrayList volumes; | |
112 | protected ArrayList volumeNames; | |
113 | ||
114 | protected boolean cachedInfo; | |
115 | ||
116 | /** | |
117 | * Constructs a new <code>Partition</code> object instance given the | |
118 | * name of the AFS partition and the AFS server, represented by | |
119 | * <CODE>server</CODE>, to which it belongs. This does not actually | |
120 | * create a new AFS partition, it just represents an existing one. | |
121 | * If <code>name</code> is not an actual AFS partition, exceptions | |
122 | * will be thrown during subsequent method invocations on this | |
123 | * object. | |
124 | * | |
125 | * @param name the name of the partition to represent | |
126 | * @param server the server on which the partition resides | |
127 | * @exception AFSException If an error occurs in the native code | |
128 | */ | |
129 | public Partition( String name, Server server ) throws AFSException | |
130 | { | |
131 | this.name = name; | |
132 | this.server = server; | |
133 | this.cell = server.getCell(); | |
134 | ||
135 | id = -1; | |
136 | ||
137 | volumes = null; | |
138 | volumeNames = null; | |
139 | ||
140 | cachedInfo = false; | |
141 | } | |
142 | ||
143 | /** | |
144 | * Constructs a new <CODE>Partition</CODE> object instance given the name | |
145 | * of the AFS partition and the AFS server, represented by | |
146 | * <CODE>server</CODE>, to which it belongs. This does not actually | |
147 | * create a new AFS partition, it just represents an existing one. | |
148 | * If <code>name</code> is not an actual AFS partition, exceptions | |
149 | * will be thrown during subsequent method invocations on this | |
150 | * object. | |
151 | * | |
152 | * <P> This constructor is ideal for point-in-time representation and | |
153 | * transient applications. It ensures all data member values are set and | |
154 | * available without calling back to the filesystem at the first request | |
155 | * for them. Use the {@link #refresh()} method to address any coherency | |
156 | * concerns. | |
157 | * | |
158 | * @param name the name of the partition to represent | |
159 | * @param server the server to which the partition belongs. | |
160 | * @param preloadAllMembers true will ensure all object members are | |
161 | * set upon construction; | |
162 | * otherwise members will be set upon access, | |
163 | * which is the default behavior. | |
164 | * @exception AFSException If an error occurs in the native code | |
165 | * @see #refresh | |
166 | */ | |
167 | public Partition( String name, Server server, boolean preloadAllMembers ) | |
168 | throws AFSException | |
169 | { | |
170 | this(name, server); | |
171 | if (preloadAllMembers) refresh(true); | |
172 | } | |
173 | ||
174 | /** | |
175 | * Creates a blank <code>Server</code> given the cell to which the partition | |
176 | * belongs and the server on which the partition resides. This blank | |
177 | * object can then be passed into other methods to fill out its properties. | |
178 | * | |
179 | * @exception AFSException If an error occurs in the native code | |
180 | * @param cell the cell to which the partition belongs. | |
181 | * @param server the server on which the partition resides | |
182 | */ | |
183 | Partition( Server server ) throws AFSException | |
184 | { | |
185 | this( null, server ); | |
186 | } | |
187 | ||
188 | /*-------------------------------------------------------------------------*/ | |
189 | ||
190 | /** | |
191 | * Refreshes the properties of this Partition object instance with values | |
192 | * from the AFS partition | |
193 | * it represents. All properties that have been initialized and/or | |
194 | * accessed will be renewed according to the values of the AFS partition | |
195 | * this Partition object instance represents. | |
196 | * | |
197 | * <P>Since in most environments administrative changes can be administered | |
198 | * from an AFS command-line program or an alternate GUI application, this | |
199 | * method provides a means to refresh the Java object representation and | |
200 | * thereby ascertain any possible modifications that may have been made | |
201 | * from such alternate administrative programs. Using this method before | |
202 | * an associated instance accessor will ensure the highest level of | |
203 | * representative accuracy, accommodating changes made external to the | |
204 | * Java application space. If administrative changes to the underlying AFS | |
205 | * system are only allowed via this API, then the use of this method is | |
206 | * unnecessary. | |
207 | * | |
208 | * @exception AFSException If an error occurs in the native code | |
209 | */ | |
210 | public void refresh() throws AFSException | |
211 | { | |
212 | refresh(false); | |
213 | } | |
214 | ||
215 | /** | |
216 | * Refreshes the properties of this Partition object instance with values | |
217 | * from the AFS partition it represents. If <CODE>all</CODE> is | |
218 | * <CODE>true</CODE> then <U>all</U> of the properties of this Partition | |
219 | * object instance will be set, or renewed, according to the values of the | |
220 | * AFS partition it represents, disregarding any previously set properties. | |
221 | * | |
222 | * <P> Thus, if <CODE>all</CODE> is <CODE>false</CODE> then properties | |
223 | * that are currently set will be refreshed and properties that are not | |
224 | * set will remain uninitialized. See {@link #refresh()} for more | |
225 | * information. | |
226 | * | |
227 | * @param all if true set or renew all object properties; otherwise | |
228 | * renew all set properties | |
229 | * @exception AFSException If an error occurs in the native code | |
230 | * @see #refresh() | |
231 | */ | |
232 | protected void refresh(boolean all) throws AFSException | |
233 | { | |
234 | if (all || volumes != null) { | |
235 | refreshVolumes(); | |
236 | } | |
237 | if (all || volumeNames != null) { | |
238 | refreshVolumeNames(); | |
239 | } | |
240 | if (all || cachedInfo) { | |
241 | refreshInfo(); | |
242 | } | |
243 | } | |
244 | ||
245 | /** | |
246 | * Refreshes the information fields of this <code>Partition</code> to | |
247 | * reflect the current state of the AFS partition. These include total | |
248 | * free space, id, etc. | |
249 | * | |
250 | * @exception AFSException If an error occurs in the native code | |
251 | */ | |
252 | protected void refreshInfo() throws AFSException | |
253 | { | |
254 | getPartitionInfo( cell.getCellHandle(), server.getVosHandle(), getID(), | |
255 | this ); | |
256 | cachedInfo = true; | |
257 | } | |
258 | ||
259 | /** | |
260 | * Obtains the most current list of <code>Volume</code> objects of this | |
261 | * partition. | |
262 | * | |
263 | * @exception AFSException If an error occurs in the native code | |
264 | */ | |
265 | protected void refreshVolumes() throws AFSException | |
266 | { | |
267 | Volume currVolume; | |
268 | ||
269 | long iterationID = getVolumesBegin( cell.getCellHandle(), | |
270 | server.getVosHandle(), getID() ); | |
271 | ||
272 | volumes = new ArrayList(); | |
273 | ||
274 | currVolume = new Volume( this ); | |
275 | while( getVolumesNext( iterationID, currVolume ) != 0 ) { | |
276 | volumes.add( currVolume ); | |
277 | currVolume = new Volume( this ); | |
278 | } | |
279 | getVolumesDone( iterationID ); | |
280 | } | |
281 | ||
282 | /** | |
283 | * Obtains the most current list of volume names of this partition. | |
284 | * | |
285 | * @exception AFSException If an error occurs in the native code | |
286 | */ | |
287 | protected void refreshVolumeNames() throws AFSException | |
288 | { | |
289 | String currName; | |
290 | ||
291 | long iterationID = getVolumesBegin( cell.getCellHandle(), | |
292 | server.getVosHandle(), getID() ); | |
293 | ||
294 | volumeNames = new ArrayList(); | |
295 | ||
296 | while( ( currName = getVolumesNextString( iterationID ) ) != null ) { | |
297 | volumeNames.add( currName ); | |
298 | } | |
299 | getVolumesDone( iterationID ); | |
300 | } | |
301 | ||
302 | /** | |
303 | * Syncs this partition to the VLDB. | |
304 | * | |
305 | * @exception AFSException If an error occurs in the native code | |
306 | */ | |
307 | public void syncPartition() throws AFSException | |
308 | { | |
309 | server.syncServerWithVLDB( cell.getCellHandle(), server.getVosHandle(), | |
310 | getID() ); | |
311 | } | |
312 | ||
313 | /** | |
314 | * Syncs the VLDB to this partition. | |
315 | * | |
316 | * @exception AFSException If an error occurs in the native code | |
317 | */ | |
318 | public void syncVLDB() throws AFSException | |
319 | { | |
320 | server.syncVLDBWithServer( cell.getCellHandle(), server.getVosHandle(), | |
321 | getID(), false ); | |
322 | } | |
323 | ||
324 | /** | |
325 | * Salvages (restores consistency to) this partition. Uses default values for | |
326 | * most salvager options in order to simplify the API. | |
327 | * | |
328 | * @exception AFSException If an error occurs in the native code | |
329 | */ | |
330 | public void salvage() throws AFSException | |
331 | { | |
332 | server.salvage( cell.getCellHandle(), server.getBosHandle(), name, null, | |
333 | 4, null, null, false, false, false, false, false, false ); | |
334 | } | |
335 | ||
336 | //////////////// accessors: //////////////////////// | |
337 | ||
338 | /** | |
339 | * Returns the name of this partition. | |
340 | * | |
341 | * @return the name of this partition | |
342 | */ | |
343 | public String getName() | |
344 | { | |
345 | return name; | |
346 | } | |
347 | ||
348 | /** | |
349 | * Returns this partition's hosting server. | |
350 | * | |
351 | * @return this partition's server | |
352 | */ | |
353 | public Server getServer() | |
354 | { | |
355 | return server; | |
356 | } | |
357 | ||
358 | /** | |
359 | * Returns the number of volumes contained in this partition. | |
360 | * | |
361 | * <P>If the total list of volumes or volume names have already been | |
362 | * collected (see {@link #getVolumes()}), then the returning value will | |
363 | * be calculated based upon the current list. Otherwise, AFS will be | |
364 | * explicitly queried for the information. | |
365 | * | |
366 | * <P> The product of this method is not saved, and is recalculated | |
367 | * with every call. | |
368 | * | |
369 | * @return the number of volumes contained in this partition. | |
370 | * @exception AFSException If an error occurs in any | |
371 | * of the associated native methods | |
372 | */ | |
373 | public int getVolumeCount() throws AFSException | |
374 | { | |
375 | if (volumes != null) { | |
376 | return volumes.size(); | |
377 | } else if (volumeNames != null) { | |
378 | return volumeNames.size(); | |
379 | } else { | |
380 | return getVolumeCount( cell.getCellHandle(), | |
381 | server.getVosHandle(), getID() ); | |
382 | } | |
383 | } | |
384 | ||
385 | /** | |
386 | * Retrieves the <CODE>Volume</CODE> object (which is an abstract | |
387 | * representation of an actual AFS volume of this partition) designated | |
388 | * by <code>name</code> (i.e. "root.afs", etc.). If a volume by | |
389 | * that name does not actually exist in AFS on the partition | |
390 | * represented by this object, an {@link AFSException} will be | |
391 | * thrown. | |
392 | * | |
393 | * @exception AFSException If an error occurs in the native code | |
394 | * @exception NullPointerException If <CODE>name</CODE> is | |
395 | * <CODE>null</CODE>. | |
396 | * @param name the name of the volume to retrieve | |
397 | * @return <CODE>Volume</CODE> designated by <code>name</code>. | |
398 | */ | |
399 | public Volume getVolume(String name) throws AFSException | |
400 | { | |
401 | if (name == null) throw new NullPointerException(); | |
402 | Volume volume = new Volume(name, this); | |
403 | return volume; | |
404 | } | |
405 | ||
406 | /** | |
407 | * Retrieves an array containing all of the <code>Volume</code> objects | |
408 | * associated with this <code>Partition</code>, each of which is an | |
409 | * abstract representation of an actual AFS volume of the AFS partition. | |
410 | * After this method is called once, it saves the array of | |
411 | * <code>Volume</code>s and returns that saved array on subsequent calls, | |
412 | * until the {@link #refresh()} method is called and a more current list | |
413 | * is obtained. | |
414 | * | |
415 | * @exception AFSException If an error occurs in the native code | |
416 | * @return a <code>Volume</code> array of the <code>Volume</code> | |
417 | * objects of the partition. | |
418 | * @see #refresh() | |
419 | */ | |
420 | public Volume[] getVolumes() throws AFSException | |
421 | { | |
422 | if (volumes == null) refreshVolumes(); | |
423 | return (Volume[]) volumes.toArray( new Volume[volumes.size()] ); | |
424 | } | |
425 | ||
426 | /** | |
427 | * Returns an array containing a subset of the <code>Volume</code> objects | |
428 | * associated with this <code>Partition</code>, each of which is an abstract | |
429 | * representation of an actual AFS volume of the AFS partition. The subset | |
430 | * is a point-in-time list of volumes (<code>Volume</code> objects | |
431 | * representing AFS volumes) starting at the complete array's index of | |
432 | * <code>startIndex</code> and containing up to <code>length</code> | |
433 | * elements. | |
434 | * | |
435 | * If <code>length</code> is larger than the number of remaining elements, | |
436 | * respective to <code>startIndex</code>, then this method will | |
437 | * ignore the remaining positions requested by <code>length</code> and | |
438 | * return an array that contains the remaining number of elements found in | |
439 | * this partition's complete array of volumes. | |
440 | * | |
441 | * <P>This method is especially useful when managing iterations of very | |
442 | * large lists. {@link #getVolumeCount()} can be used to determine if | |
443 | * iteration management is practical. | |
444 | * | |
445 | * <P>This method does not save the resulting data and therefore | |
446 | * queries AFS for each call. | |
447 | * | |
448 | * <P><B>Example:</B> If there are more than 50,000 volumes within this partition | |
449 | * then only render them in increments of 10,000. | |
450 | * <PRE> | |
451 | * ... | |
452 | * Volume[] volumes; | |
453 | * if (partition.getVolumeCount() > 50000) { | |
454 | * int index = 0; | |
455 | * int length = 10000; | |
456 | * while (index < partition.getVolumeCount()) { | |
457 | * volumes = partition.<B>getVolumes</B>(index, length); | |
458 | * for (int i = 0; i < volumes.length; i++) { | |
459 | * ... | |
460 | * } | |
461 | * index += length; | |
462 | * ... | |
463 | * } | |
464 | * } else { | |
465 | * volumes = partition.getVolumes(); | |
466 | * for (int i = 0; i < volumes.length; i++) { | |
467 | * ... | |
468 | * } | |
469 | * } | |
470 | * ... | |
471 | * </PRE> | |
472 | * | |
473 | * @param startIndex the base zero index position at which the subset array | |
474 | * should start from, relative to the complete list of | |
475 | * elements present in AFS. | |
476 | * @param length the number of elements that the subset should contain | |
477 | * @return a subset array of volumes hosted by this partition | |
478 | * @exception AFSException If an error occurs in the native code | |
479 | * @see #getVolumeCount() | |
480 | * @see #getVolumeNames(int, int) | |
481 | * @see #getVolumes() | |
482 | */ | |
483 | public Volume[] getVolumes(int startIndex, int length) throws AFSException | |
484 | { | |
485 | Volume[] volumes = new Volume[length]; | |
486 | Volume currVolume = new Volume( this ); | |
487 | int i = 0; | |
488 | ||
489 | long iterationID = getVolumesBeginAt( cell.getCellHandle(), | |
490 | server.getVosHandle(), getID(), startIndex ); | |
491 | ||
492 | while( getVolumesNext( iterationID, currVolume ) != 0 && i < length ) { | |
493 | volumes[i] = currVolume; | |
494 | currVolume = new Volume( this ); | |
495 | i++; | |
496 | } | |
497 | getVolumesDone( iterationID ); | |
498 | if (i < length) { | |
499 | Volume[] v = new Volume[i]; | |
500 | System.arraycopy(volumes, 0, v, 0, i); | |
501 | return v; | |
502 | } else { | |
503 | return volumes; | |
504 | } | |
505 | } | |
506 | ||
507 | /** | |
508 | * Retrieves an array containing all of the names of volumes | |
509 | * associated with this <code>Partition</code>. | |
510 | * After this method is called once, it saves the array of | |
511 | * <code>String</code>s and returns that saved array on subsequent calls, | |
512 | * until the {@link #refresh()} method is called and a more current | |
513 | * list is obtained. | |
514 | * | |
515 | * @return a <code>String</code> array of the volumes of the partition. | |
516 | * @exception AFSException If an error occurs in the native code | |
517 | * @see #refresh() | |
518 | */ | |
519 | public String[] getVolumeNames() throws AFSException | |
520 | { | |
521 | if (volumeNames == null) refreshVolumeNames(); | |
522 | return (String []) volumeNames.toArray( new String[volumeNames.size() ] ); | |
523 | } | |
524 | ||
525 | /** | |
526 | * Returns an array containing a subset of the names of volumes | |
527 | * associated with this <code>Partition</code>. The subset is a | |
528 | * point-in-time list of volume names starting at the complete array's | |
529 | * index of <code>startIndex</code> and containing up to <code>length</code> | |
530 | * elements. | |
531 | * | |
532 | * If <code>length</code> is larger than the number of remaining elements, | |
533 | * respective to <code>startIndex</code>, then this method will | |
534 | * ignore the remaining positions requested by <code>length</code> and | |
535 | * return an array that contains the remaining number of elements found in | |
536 | * this partition's complete array of volume names. | |
537 | * | |
538 | * <P>This method is especially useful when managing iterations of very | |
539 | * large lists. {@link #getVolumeCount()} can be used to determine if | |
540 | * iteration management is practical. | |
541 | * | |
542 | * <P>This method does not save the resulting data and therefore | |
543 | * queries AFS for each call. | |
544 | * | |
545 | * <P><B>Example:</B> If there are more than 50,000 volumes within this partition | |
546 | * then only render them in increments of 10,000. | |
547 | * <PRE> | |
548 | * ... | |
549 | * String[] volumes; | |
550 | * if (partition.getVolumeCount() > 50000) { | |
551 | * int index = 0; | |
552 | * int length = 10000; | |
553 | * while (index < partition.getVolumeCount()) { | |
554 | * volumes = partition.<B>getVolumeNames</B>(index, length); | |
555 | * for (int i = 0; i < volumes.length; i++) { | |
556 | * ... | |
557 | * } | |
558 | * index += length; | |
559 | * ... | |
560 | * } | |
561 | * } else { | |
562 | * volumes = partition.getVolumeNames(); | |
563 | * for (int i = 0; i < volumes.length; i++) { | |
564 | * ... | |
565 | * } | |
566 | * } | |
567 | * ... | |
568 | * </PRE> | |
569 | * | |
570 | * @param startIndex the base zero index position at which the subset array | |
571 | * should start from, relative to the complete list of | |
572 | * elements present in AFS. | |
573 | * @param length the number of elements that the subset should contain | |
574 | * @return a subset array of volume names hosted by this partition | |
575 | * @exception AFSException If an error occurs in the native code | |
576 | * @see #getVolumeCount() | |
577 | * @see #getVolumes(int, int) | |
578 | * @see #getVolumes() | |
579 | */ | |
580 | public String[] getVolumeNames(int startIndex, int length) throws AFSException | |
581 | { | |
582 | String[] volumes = new String[length]; | |
583 | String currName; | |
584 | int i = 0; | |
585 | ||
586 | long iterationID = getVolumesBeginAt( cell.getCellHandle(), | |
587 | server.getVosHandle(), getID(), startIndex ); | |
588 | ||
589 | while( ( currName = getVolumesNextString( iterationID ) ) != null && i < length ) { | |
590 | volumes[i] = currName; | |
591 | i++; | |
592 | } | |
593 | getVolumesDone( iterationID ); | |
594 | if (i < length) { | |
595 | String[] v = new String[i]; | |
596 | System.arraycopy(volumes, 0, v, 0, i); | |
597 | return v; | |
598 | } else { | |
599 | return volumes; | |
600 | } | |
601 | } | |
602 | ||
603 | /** | |
604 | * Returns the id of this partition (i.e. "vicepa" = 0, etc.) | |
605 | * | |
606 | * @exception AFSException If an error occurs in the native code | |
607 | * @return the id of this partition | |
608 | */ | |
609 | public int getID() throws AFSException | |
610 | { | |
611 | if (id == -1) id = translateNameToID( name ); | |
612 | return id; | |
613 | } | |
614 | ||
615 | /** | |
616 | * Returns the device name of this partition (i.e. "hda5", etc.) | |
617 | * | |
618 | * @exception AFSException If an error occurs in the native code | |
619 | * @return the device name of this partition | |
620 | * @see #refresh() | |
621 | */ | |
622 | public String getDeviceName() throws AFSException | |
623 | { | |
624 | if (!cachedInfo) refreshInfo(); | |
625 | return deviceName; | |
626 | } | |
627 | ||
628 | /** | |
629 | * Returns the lock file descriptor of this partition | |
630 | * | |
631 | * @exception AFSException If an error occurs in the native code | |
632 | * @return the lock file descriptor of this partition | |
633 | * @see #refresh() | |
634 | */ | |
635 | public int getLockFileDescriptor() throws AFSException | |
636 | { | |
637 | if (!cachedInfo) refreshInfo(); | |
638 | return lockFileDescriptor; | |
639 | } | |
640 | ||
641 | /** | |
642 | * Returns the total space on this partition. | |
643 | * | |
644 | * @exception AFSException If an error occurs in the native code | |
645 | * @return the total space on this partition | |
646 | * @see #refresh() | |
647 | */ | |
648 | public int getTotalSpace() throws AFSException | |
649 | { | |
650 | if (!cachedInfo) refreshInfo(); | |
651 | return totalSpace; | |
652 | } | |
653 | ||
654 | /** | |
655 | * Returns the total free space on this partition. | |
656 | * After this method is called once, it saves the total free space | |
657 | * and returns that value on subsequent calls, | |
658 | * until the {@link #refresh()} method is called and a more current | |
659 | * value is obtained. | |
660 | * | |
661 | * @exception AFSException If an error occurs in the native code | |
662 | * @return the total free space on this partition | |
663 | * @see #refresh() | |
664 | */ | |
665 | public int getTotalFreeSpace() throws AFSException | |
666 | { | |
667 | if (!cachedInfo) refreshInfo(); | |
668 | return totalFreeSpace; | |
669 | } | |
670 | ||
671 | /** | |
672 | * Returns the total used space on this partition. | |
673 | * After this method is called once, it saves the total used space | |
674 | * and returns that value on subsequent calls, | |
675 | * until the {@link #refresh()} method is called and a more current | |
676 | * value is obtained. | |
677 | * | |
678 | * @exception AFSException If an error occurs in the native code | |
679 | * @return the total used space on this partition | |
680 | * @see #refresh() | |
681 | */ | |
682 | public int getUsedSpace() throws AFSException | |
683 | { | |
684 | if (!cachedInfo) refreshInfo(); | |
685 | return (totalSpace - totalFreeSpace); | |
686 | } | |
687 | ||
688 | /** | |
689 | * Returns the total combined quota of all volumes on this partition, | |
690 | * unless a volume has configured an unlimited quota at which case an | |
691 | * {@link AFSException} is thrown. | |
692 | * | |
693 | * <P>After this method is called once, it saves the value and returns | |
694 | * that value on subsequent calls, until the {@link #refresh()} | |
695 | * method is called and a more current value is obtained. | |
696 | * | |
697 | * @exception AFSException If an error occurs while retrieving and | |
698 | * calculating, or a volume has an | |
699 | * unlimited quota. | |
700 | * @return the total combined quota of all volumes on this partition | |
701 | * @see #getTotalQuota(boolean) | |
702 | * @see #hasVolumeWithUnlimitedQuota() | |
703 | * @see Volume#getQuota() | |
704 | */ | |
705 | public int getTotalQuota() throws AFSException | |
706 | { | |
707 | return getTotalQuota(false); | |
708 | } | |
709 | ||
710 | /** | |
711 | * Returns the total combined quota of all volumes on this partition, | |
712 | * ignoring volumes with unlimited quotas, if <CODE> | |
713 | * ignoreUnlimitedQuotas</CODE> is <CODE>true</CODE>; otherwise an | |
714 | * {@link AFSException} is thrown if a volume has an unlimited quota. | |
715 | * | |
716 | * <P>After this method is called once, it saves the value and returns | |
717 | * that value on subsequent calls, until the {@link #refresh()} | |
718 | * method is called and a more current value is obtained. | |
719 | * | |
720 | * @exception AFSException If an error occurs while retrieving and | |
721 | * calculating, or a volume has an | |
722 | * unlimited quota. | |
723 | * @return the total combined quota of all volumes on this partition | |
724 | * @see #getTotalQuota() | |
725 | * @see #hasVolumeWithUnlimitedQuota() | |
726 | * @see Volume#getQuota() | |
727 | * @see #refresh() | |
728 | */ | |
729 | public int getTotalQuota(boolean ignoreUnlimitedQuotas) | |
730 | throws AFSException | |
731 | { | |
732 | if (volumes == null) refreshVolumes(); | |
733 | if (totalQuota == 0 || !ignoreUnlimitedQuotas) { | |
734 | Volume[] volumes = getVolumes(); | |
735 | for (int i = 0; i < volumes.length; i++) { | |
736 | try { | |
737 | totalQuota += volumes[i].getQuota(); | |
738 | } catch (AFSException e) { | |
739 | if (!ignoreUnlimitedQuotas) { | |
740 | totalQuota = 0; | |
741 | throw e; | |
742 | } | |
743 | } | |
744 | } | |
745 | } | |
746 | return totalQuota; | |
747 | } | |
748 | ||
749 | /** | |
750 | * Tests whether this partition contains a volume that has an unlimited | |
751 | * quota configured. | |
752 | * | |
753 | * @exception AFSException If an error occurs in the native code | |
754 | * @return <CODE>true</CODE> if a contained volume's quota is configured | |
755 | * as unlimited; otherwise <CODE>false</CODE>. | |
756 | * @see #getTotalQuota() | |
757 | * @see #getTotalQuota(boolean) | |
758 | * @see Volume#isQuotaUnlimited() | |
759 | * @see Volume#getQuota() | |
760 | * @see #refresh() | |
761 | */ | |
762 | public boolean hasVolumeWithUnlimitedQuota() throws AFSException | |
763 | { | |
764 | if (volumes == null) refreshVolumes(); | |
765 | Volume[] volumes = getVolumes(); | |
766 | for (int i = 0; i < volumes.length; i++) { | |
767 | if (volumes[i].isQuotaUnlimited()) return true; | |
768 | } | |
769 | return false; | |
770 | } | |
771 | ||
772 | /////////////// custom information methods //////////////////// | |
773 | ||
774 | /** | |
775 | * Returns a <code>String</code> representation of this | |
776 | * <code>Partition</code>. Contains the information fields and a list of | |
777 | * volumes. | |
778 | * | |
779 | * @return a <code>String</code> representation of the <code>Partition</code> | |
780 | */ | |
781 | public String getInfo() | |
782 | { | |
783 | String r; | |
784 | ||
785 | try { | |
786 | ||
787 | r = "Partition: " + name + "\tid: " + getID() + "\n"; | |
788 | ||
789 | r += "\tDevice name: " + getDeviceName() + "\n"; | |
790 | r += "\tLock file descriptor: " + getLockFileDescriptor() + "\n"; | |
791 | r += "\tTotal free space: " + getTotalFreeSpace() + " K\n"; | |
792 | r += "\tTotal space: " + getTotalSpace() + " K\n"; | |
793 | ||
794 | r += "\tVolumes:\n"; | |
795 | ||
796 | String vols[] = getVolumeNames(); | |
797 | ||
798 | for( int i = 0; i < vols.length; i++ ) { | |
799 | r += "\t\t" + vols[i] + "\n"; | |
800 | } | |
801 | ||
802 | } catch( Exception e ) { | |
803 | return e.toString(); | |
804 | } | |
805 | return r; | |
806 | } | |
807 | ||
808 | /** | |
809 | * Returns a <code>String</code> containing the <code>String</code> | |
810 | * representations of all the volumes of this <code>Partition</code>. | |
811 | * | |
812 | * @return a <code>String</code> representation of the volumes | |
813 | * @see Volume#getInfo | |
814 | */ | |
815 | public String getInfoVolumes() throws AFSException | |
816 | { | |
817 | String r; | |
818 | ||
819 | r = "Partition: " + name + "\n\n"; | |
820 | r += "--Volumes--\n"; | |
821 | ||
822 | Volume vols[] = getVolumes(); | |
823 | for( int i = 0; i < vols.length; i++ ) { | |
824 | r += vols[i].getInfo() + "\n"; | |
825 | } | |
826 | return r; | |
827 | } | |
828 | ||
829 | /////////////// custom override methods //////////////////// | |
830 | ||
831 | /** | |
832 | * Compares two Partition objects respective to their names and does not | |
833 | * factor any other attribute. Alphabetic case is significant in | |
834 | * comparing names. | |
835 | * | |
836 | * @param partition The Partition object to be compared to | |
837 | * this Partition instance | |
838 | * | |
839 | * @return Zero if the argument is equal to this Partition's name, a | |
840 | * value less than zero if this Partition's name is | |
841 | * lexicographically less than the argument, or a value greater | |
842 | * than zero if this Partition's name is lexicographically | |
843 | * greater than the argument | |
844 | */ | |
845 | public int compareTo(Partition partition) | |
846 | { | |
847 | return this.getName().compareTo(partition.getName()); | |
848 | } | |
849 | ||
850 | /** | |
851 | * Comparable interface method. | |
852 | * | |
853 | * @see #compareTo(Partition) | |
854 | */ | |
855 | public int compareTo(Object obj) | |
856 | { | |
857 | return compareTo((Partition)obj); | |
858 | } | |
859 | ||
860 | /** | |
861 | * Tests whether two <code>Partition</code> objects are equal, | |
862 | * based on their names and hosting server. | |
863 | * | |
864 | * @param otherPartition the Partition to test | |
865 | * @return whether the specifed Partition is the same as this Partition | |
866 | */ | |
867 | public boolean equals( Partition otherPartition ) | |
868 | { | |
869 | return ( name.equals(otherPartition.getName()) ) && | |
870 | ( getServer().equals(otherPartition.getServer()) ); | |
871 | } | |
872 | ||
873 | /** | |
874 | * Returns the name of this <CODE>Partition</CODE> | |
875 | * | |
876 | * @return the name of this <CODE>Partition</CODE> | |
877 | */ | |
878 | public String toString() | |
879 | { | |
880 | return getName(); | |
881 | } | |
882 | ||
883 | /////////////// native methods //////////////////// | |
884 | ||
885 | /** | |
886 | * Fills in the information fields of the provided <code>Partition</code>. | |
887 | * | |
888 | * @param cellHandle the handle of the cell to which the partition belongs | |
889 | * @see Cell#getCellHandle | |
890 | * @param serverHandle the vos handle of the server on which the | |
891 | * partition resides | |
892 | * @see Server#getVosServerHandle | |
893 | * @param partition the numeric id of the partition for which to get the | |
894 | * info | |
895 | * @param thePartition the {@link Partition Partition} object in which to | |
896 | * fill in the information | |
897 | * @exception AFSException If an error occurs in the native code | |
898 | */ | |
899 | protected static native void getPartitionInfo( long cellHandle, | |
900 | long serverHandle, | |
901 | int partition, | |
902 | Partition thePartition ) | |
903 | throws AFSException; | |
904 | ||
905 | /** | |
906 | * Returns the total number of volumes hosted by this partition. | |
907 | * | |
908 | * @param cellHandle the handle of the cell to which the partition belongs | |
909 | * @param serverHandle the vos handle of the server to which the partition | |
910 | * belongs | |
911 | * @param partition the numeric id of the partition on which the volumes | |
912 | * reside | |
913 | * @return total number of volumes hosted by this partition | |
914 | * @exception AFSException If an error occurs in the native code | |
915 | * @see Cell#getCellHandle | |
916 | * @see Server#getVosServerHandle | |
917 | */ | |
918 | protected static native int getVolumeCount( long cellHandle, | |
919 | long serverHandle, | |
920 | int partition ) | |
921 | throws AFSException; | |
922 | ||
923 | /** | |
924 | * Begin the process of getting the volumes on a partition. Returns | |
925 | * an iteration ID to be used by subsequent calls to | |
926 | * <code>getVolumesNext</code> and <code>getVolumesDone</code>. | |
927 | * | |
928 | * @param cellHandle the handle of the cell to which the partition belongs | |
929 | * @see Cell#getCellHandle | |
930 | * @param serverHandle the vos handle of the server to which the partition | |
931 | * belongs | |
932 | * @see Server#getVosServerHandle | |
933 | * @param partition the numeric id of the partition on which the volumes | |
934 | * reside | |
935 | * @return an iteration ID | |
936 | * @exception AFSException If an error occurs in the native code | |
937 | */ | |
938 | protected static native long getVolumesBegin( long cellHandle, | |
939 | long serverHandle, | |
940 | int partition ) | |
941 | throws AFSException; | |
942 | ||
943 | /** | |
944 | * Begin the process of getting the volumes on a partition. Returns | |
945 | * an iteration ID to be used by subsequent calls to | |
946 | * <code>getVolumesNext</code> and <code>getVolumesDone</code>. | |
947 | * | |
948 | * @param cellHandle the handle of the cell to which the partition belongs | |
949 | * @see Cell#getCellHandle | |
950 | * @param serverHandle the vos handle of the server to which the partition | |
951 | * belongs | |
952 | * @see Server#getVosServerHandle | |
953 | * @param partition the numeric id of the partition on which the volumes | |
954 | * reside | |
955 | * @return an iteration ID | |
956 | * @exception AFSException If an error occurs in the native code | |
957 | */ | |
958 | protected static native long getVolumesBeginAt( long cellHandle, | |
959 | long serverHandle, | |
960 | int partition, int index ) | |
961 | throws AFSException; | |
962 | ||
963 | /** | |
964 | * Returns the next volume of the partition. Returns <code>null</code> | |
965 | * if there are no more volumes. | |
966 | * | |
967 | * @param iterationId the iteration ID of this iteration | |
968 | * @see #getVolumesBegin | |
969 | * @return the name of the next volume of the server | |
970 | * @exception AFSException If an error occurs in the native code | |
971 | */ | |
972 | protected static native String getVolumesNextString( long iterationId ) | |
973 | throws AFSException; | |
974 | ||
975 | /** | |
976 | * Fills the next volume object of the partition. Returns 0 if there | |
977 | * are no more volumes, != 0 otherwise. | |
978 | * | |
979 | * @param iterationId the iteration ID of this iteration | |
980 | * @param theVolume the Volume object in which to fill the values | |
981 | * of the next volume | |
982 | * @see #getVolumesBegin | |
983 | * @return 0 if there are no more volumes, != 0 otherwise | |
984 | * @exception AFSException If an error occurs in the native code | |
985 | */ | |
986 | protected static native int getVolumesNext( long iterationId, | |
987 | Volume theVolume ) | |
988 | throws AFSException; | |
989 | ||
990 | /** | |
991 | * Fills the next volume object of the partition. Returns 0 if there | |
992 | * are no more volumes, != 0 otherwise. | |
993 | * | |
994 | * @param iterationId the iteration ID of this iteration | |
995 | * @param theVolume the Volume object in which to fill the values of the | |
996 | * next volume | |
997 | * @see #getVolumesBegin | |
998 | * @return 0 if there are no more volumes, != 0 otherwise | |
999 | * @exception AFSException If an error occurs in the native code | |
1000 | */ | |
1001 | protected static native int getVolumesAdvanceTo( long iterationId, | |
1002 | Volume theVolume, | |
1003 | int advanceCount ) | |
1004 | throws AFSException; | |
1005 | ||
1006 | /** | |
1007 | * Signals that the iteration is complete and will not be accessed anymore. | |
1008 | * | |
1009 | * @param iterationId the iteration ID of this iteration | |
1010 | * @see #getVolumesBegin | |
1011 | * @exception AFSException If an error occurs in the native code | |
1012 | */ | |
1013 | protected static native void getVolumesDone( long iterationId ) | |
1014 | throws AFSException; | |
1015 | ||
1016 | /** | |
1017 | * Translates a partition name into a partition id | |
1018 | * | |
1019 | * @param name the name of the partition in question | |
1020 | * @return the id of the partition in question | |
1021 | * @exception AFSException If an error occurs in the native code | |
1022 | */ | |
1023 | protected static native int translateNameToID( String name ) | |
1024 | throws AFSException; | |
1025 | ||
1026 | /** | |
1027 | * Translates a partition id into a partition name | |
1028 | * | |
1029 | * @param id the id of the partition in question | |
1030 | * @return the name of the partition in question | |
1031 | * @exception AFSException If an error occurs in the native code | |
1032 | */ | |
1033 | protected static native String translateIDToName( int id ) | |
1034 | throws AFSException; | |
1035 | ||
1036 | /** | |
1037 | * Reclaims all memory being saved by the partition portion of the native | |
1038 | * library. This method should be called when no more <code>Partition</code> | |
1039 | * objects are expected to be | |
1040 | * used. | |
1041 | */ | |
1042 | protected static native void reclaimPartitionMemory(); | |
1043 | } | |
1044 | ||
1045 | ||
1046 | ||
1047 | ||
1048 | ||
1049 | ||
1050 | ||
1051 | ||
1052 |