Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / JAVA / classes / org / openafs / jafs / Partition.java
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