001/***************************************************************************** 002 * Copyright by The HDF Group. * 003 * Copyright by the Board of Trustees of the University of Illinois. * 004 * All rights reserved. * 005 * * 006 * This file is part of the HDF Java Products distribution. * 007 * The full copyright notice, including terms governing use, modification, * 008 * and redistribution, is contained in the files COPYING and Copyright.html. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * Or, see http://hdfgroup.org/products/hdf-java/doc/Copyright.html. * 011 * If you do not have access to either file, you may request a copy from * 012 * help@hdfgroup.org. * 013 ****************************************************************************/ 014 015package hdf.object; 016 017import java.util.Enumeration; 018import java.util.List; 019import java.util.Vector; 020 021import javax.swing.tree.DefaultMutableTreeNode; 022 023/** 024 * Group is an abstract class. Current implementing classes are the H4Group and 025 * H5Group. This class includes general information of a group object such as 026 * members of a group and common operations on groups. 027 * <p> 028 * Members of a group may include other groups, datasets or links. 029 * <p> 030 * 031 * @version 1.1 9/4/2007 032 * @author Peter X. Cao 033 */ 034public abstract class Group extends HObject { 035 036 /** 037 * 038 */ 039 private static final long serialVersionUID = 3913174542591568052L; 040 041 /** 042 * The list of members (Groups and Datasets) of this group in memory. 043 */ 044 private List<HObject> memberList; 045 046 /** 047 * The parent group where this group is located. The parent of the root 048 * group is null. 049 */ 050 protected Group parent; 051 052 /** 053 * Total number of (Groups and Datasets) of this group in file. 054 */ 055 protected int nMembersInFile; 056 057 public static final int LINK_TYPE_HARD = 0; 058 059 public static final int LINK_TYPE_SOFT = 1; 060 061 public static final int LINK_TYPE_EXTERNAL = 64; 062 063 public static final int CRT_ORDER_TRACKED = 1; 064 065 public static final int CRT_ORDER_INDEXED = 2; 066 067 068 /** 069 * Constructs an instance of the group with specific name, path and parent 070 * group. An HDF data object must have a name. The path is the group path 071 * starting from the root. The parent group is the group where this group is 072 * located. 073 * <p> 074 * For example, in H5Group(h5file, "grp", "/groups/", pgroup), "grp" is the 075 * name of the group, "/groups/" is the group path of the group, and pgroup 076 * the group where "grp" is located. 077 * 078 * @param theFile 079 * the file which containing the group. 080 * @param name 081 * the name of this group, e.g. "grp01". 082 * @param path 083 * the full path of this group, e.g. "/groups/". 084 * @param parent 085 * the parent of this group. 086 */ 087 public Group(FileFormat theFile, String name, String path, Group parent) { 088 this(theFile, name, path, parent, null); 089 } 090 091 /** 092 * @deprecated Not for public use in the future.<br> 093 * Using {@link #Group(FileFormat, String, String, Group)} 094 */ 095 @Deprecated 096 public Group(FileFormat theFile, String name, String path, Group parent, 097 long[] oid) { 098 super(theFile, name, path, oid); 099 100 this.parent = parent; 101 } 102 103 /** 104 * Clears up member list and other resources in memory for the group. Since 105 * the destructor will clear memory space, the function is usually not 106 * needed. 107 */ 108 public void clear() { 109 if (memberList != null) { 110 ((Vector<HObject>) memberList).setSize(0); 111 } 112 } 113 114 /** 115 * Adds an object to the member list of this group in memory. 116 * <p> 117 * 118 * @param object 119 * the HObject (Group or Dataset) to be added to the member list. 120 */ 121 public void addToMemberList(HObject object) { 122 if (memberList == null) { 123 int size = Math.min(getNumberOfMembersInFile(), this 124 .getFileFormat().getMaxMembers()); 125 memberList = new Vector<HObject>(size + 5); 126 } 127 128 if ((object != null) && !memberList.contains(object)) { 129 memberList.add(object); 130 } 131 } 132 133 /** 134 * Removes an object from the member list of this group in memory. 135 * <p> 136 * 137 * @param object 138 * the HObject (Group or Dataset) to be removed from the member 139 * list. 140 */ 141 public void removeFromMemberList(HObject object) { 142 if (memberList != null) { 143 memberList.remove(object); 144 } 145 } 146 147 /** 148 * Returns the list of members of this group. The list is an java.awt.List 149 * containing Groups and Datasets. 150 * 151 * @return the list of members of this group. 152 */ 153 public List<HObject> getMemberList() { 154 FileFormat theFile = this.getFileFormat(); 155 String thePath = this.getPath(); 156 String theName = this.getName(); 157 158 if ((memberList == null) && (theFile != null)) { 159 int size = Math.min(getNumberOfMembersInFile(), this 160 .getFileFormat().getMaxMembers()); 161 memberList = new Vector<HObject>(size + 5); // avoid infinite loop search for 162 // groups without member 163 164 // find the memberList from the file by check the group path and 165 // name 166 // group may be created out of the structure tree 167 // (H4/5File.loadTree()). 168 try { 169 theFile.open(); 170 } // load the file structure; 171 catch (Exception ex) { 172 ; 173 } 174 175 DefaultMutableTreeNode root = (DefaultMutableTreeNode) theFile 176 .getRootNode(); 177 178 if (root == null) { 179 return memberList; 180 } 181 182 Enumeration<?> emu = root.depthFirstEnumeration(); 183 184 Group g = null; 185 Object uObj = null; 186 while (emu.hasMoreElements()) { 187 uObj = ((DefaultMutableTreeNode) emu.nextElement()) 188 .getUserObject(); 189 if (uObj instanceof Group) { 190 g = (Group) uObj; 191 if (g.getPath() != null) // add this check to get rid of 192 // null exception 193 { 194 if ((this.isRoot() && g.isRoot()) 195 || (thePath.equals(g.getPath()) && g.getName() 196 .endsWith(theName))) { 197 memberList = g.getMemberList(); 198 break; 199 } 200 } 201 } 202 } 203 } 204 205 return memberList; 206 } 207 208 /** 209 * Sets the name of the group. 210 * <p> 211 * setName (String newName) changes the name of the group in memory and 212 * file. 213 * <p> 214 * setName() updates the path in memory for all the objects that are under 215 * the group with the new name. 216 * 217 * @param newName 218 * The new name of the group. 219 */ 220 @Override 221 public void setName(String newName) throws Exception { 222 super.setName(newName); 223 224 if (memberList != null) { 225 int n = memberList.size(); 226 HObject theObj = null; 227 for (int i = 0; i < n; i++) { 228 theObj = memberList.get(i); 229 theObj.setPath(this.getPath() + newName + HObject.separator); 230 } 231 } 232 } 233 234 /** Returns the parent group. */ 235 public final Group getParent() { 236 return parent; 237 } 238 239 /** 240 * Checks if it is a root group. 241 * 242 * @return true if the group is a root group; otherwise, returns false. 243 */ 244 public final boolean isRoot() { 245 return (parent == null); 246 } 247 248 /** 249 * Returns the total number of members of this group in file. 250 * 251 * Current Java application such as HDFView cannot handle files with large 252 * numbers of objects (1,000,000 or more objects) due to JVM memory 253 * limitation. The max_members is used so that applications such as HDFView 254 * will load up to <i>max_members</i> number of objects. If the number of 255 * objects in file is larger than <i>max_members</i>, only 256 * <i>max_members</i> are loaded in memory. 257 * <p> 258 * getNumberOfMembersInFile() returns the number of objects in this group. 259 * The number of objects in memory is obtained by getMemberList().size(). 260 * 261 * @return Total number of members of this group in the file. 262 */ 263 public int getNumberOfMembersInFile() { 264 return nMembersInFile; 265 } 266}