/******************************************************************************* * Copyright (c) 2003, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jst.j2ee.internal.web.operations; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import com.ibm.icu.util.StringTokenizer; import java.util.Vector; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin; import org.eclipse.jst.j2ee.internal.project.ProjectSupportResourceHandler; import org.eclipse.jst.j2ee.internal.web.plugin.WebPlugin; /** * This class stores the relationship between two files. In particular, this is an inLink and the * files which reference it. */ public class RelationData { public class Link implements Cloneable { private String url; private int occurrences = 0; public Link(String newUrl, int occ) { url = newUrl; occurrences = occ; } /** * Returns an exact copy of this object. * * @return Created clone object */ @Override public Object clone() { return new Link(url, occurrences); } /** * Returns the url of the file that references this inLink * * @return String */ public String getURL() { return url; } /** * Returns the number of times this file references the inLink * * @return int */ public int getOccurrences() { return occurrences; } private int addOccurrence(int add) { occurrences = occurrences + add; return occurrences; } @Override public String toString() { return url; } } // our relationship table. Key is a string which is the path of the inLink, // value is a vector of files that reference the inLink. protected Hashtable inLinksTable = null; protected Hashtable anchorsTable = null; private static final int INIT_HASH_TABLE_SIZE = 100; private static final int INIT_ANCHORS_HASH_TABLE_SIZE = 10; private boolean fileOk = false; private static final String LINK_STATE_FILE_NAME = "link_table_states.txt";//$NON-NLS-1$ private static final String LINK_SERVERCONTEXTROOT_FILE_NAME = "link_scr_states.txt";//$NON-NLS-1$ public static final String LINK_MISSING_FILE = "-";//$NON-NLS-1$ public static final String LINK_INDEX_SEPARATOR = "+";//$NON-NLS-1$ public static final String ANCHOR_INDEX_SEPARATOR = "#";//$NON-NLS-1$ public static final String LINK_OCCURENCE_SEPARATOR = "/";//$NON-NLS-1$ public static final String ANCHOR_SEPARATOR = "#### ANCHORS ####";//$NON-NLS-1$ /** * RelationData constructor comment. */ public RelationData() { super(); inLinksTable = new Hashtable(INIT_HASH_TABLE_SIZE); anchorsTable = new Hashtable(INIT_ANCHORS_HASH_TABLE_SIZE); } public Link addInLink(String file_path, String parent_path, int occurence) { Vector in_links = (Vector) inLinksTable.get(file_path); if (in_links == null) { return null; } for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); // // Increment the occurence and return // if (url.compareTo(parent_path) == 0) { inlnk.addOccurrence(occurence); return inlnk; } } // // The link does not exist, need to add an entry in the table for it // Link inlnk = new Link(parent_path, occurence); in_links.addElement(inlnk); return inlnk; } public void changeInLink(String filePath, boolean missing) { if (missing) { Vector inlinks = (Vector) inLinksTable.remove(filePath); inLinksTable.put(LINK_MISSING_FILE + filePath, inlinks); } else { Vector inlinks = (Vector) inLinksTable.remove(LINK_MISSING_FILE + filePath); inLinksTable.put(filePath, inlinks); } } /* * returns which projects depend on this file i.e. any projects that are in this file's list of * in_links */ public Collection getDependentProjects(String file_path) { Hashtable outProjects = new Hashtable(); Vector in_links = (Vector) inLinksTable.get(file_path); if (in_links != null) { for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); // should be in the form of: /ProjName/.... if (url.length() > 0) { // key could be the filename or the missing filename ("-" + filename) // take this into account and offset the index accordingly int index = 0; int offset = 1; if (url.charAt(0) == '-') { index = url.indexOf(IPath.SEPARATOR, 2); offset = 2; } else { index = url.indexOf(IPath.SEPARATOR, 1); offset = 1; } if (index != -1) { String projName = url.substring(offset, index); outProjects.put(projName, projName); } } } } return outProjects.values(); } /* * returns which cross-project files depend on this file i.e. any projects that are in this * file's list of in_links */ public Collection getDependentProjectFiles(String projName) { Hashtable outProjects = new Hashtable(); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String path = (String) aenum.nextElement(); // should be in the form of: /ProjName/.... if (path.length() > 0) { // if path is a missing filename ("-" + filename) then it means that it had // to come from this project (that is, the external nonexistent file could not have // linked to this project). So, we will not add this path. Also, since it is marked // broken, it probably won't exist to do anything with it anyway. if (path.charAt(0) != '-') { int index = path.indexOf(IPath.SEPARATOR, 1); if (index != -1) { String currentProjName = path.substring(1, index); if (!currentProjName.equals(projName)) { outProjects.put(path, path); } } } } } return outProjects.values(); } public void createInLinkEntry(String file_path, String parent_path, int occurence) { Vector in_links = new Vector(); Link inlnk = new Link(parent_path, occurence); in_links.addElement(inlnk); inLinksTable.put(file_path, in_links); } public void dump() { // if (false) { // if (inLinksTable != null) { // for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { // StringBuffer St = new StringBuffer(); // String key = (String) aenum.nextElement(); // St.append("\nKey=" + key + "\n");//$NON-NLS-1$//$NON-NLS-2$ // Vector in_links = (Vector) inLinksTable.get(key); // int nb_of_links = in_links.size(); // // // Replace the string by index // // Add a '+'separator only for more than one links to save space // // // // // for (int i = 0; i < nb_of_links; i++) { // Link lnk = (Link) in_links.elementAt(i); // St.append("\tValue=" + lnk.getURL() + "[" + lnk.getOccurrences() + "]");//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ // } // org.eclipse.jem.util.logger.proxy.Logger.getLogger().logInfo(St.toString()); // } // } // } } public void dump(boolean dump) { if (dump) { if (inLinksTable != null) { for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { StringBuffer St = new StringBuffer(); String key = (String) aenum.nextElement(); St.append("\nKey=" + key + "\n");//$NON-NLS-1$//$NON-NLS-2$ Vector in_links = (Vector) inLinksTable.get(key); int nb_of_links = in_links.size(); // Replace the string by index // Add a '+'separator only for more than one links to save space // for (int i = 0; i < nb_of_links; i++) { Link lnk = (Link) in_links.elementAt(i); St.append("\tValue=" + lnk.getURL() + "[" + lnk.getOccurrences() + "]");//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ } WebPlugin.logError(St.toString()); } } } } /** * used for LinksBuilder debugging */ public void dump2() { if (inLinksTable != null) { for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { StringBuffer St = new StringBuffer(); String key = (String) aenum.nextElement(); Vector in_links = (Vector) inLinksTable.get(key); int nb_of_links = in_links.size(); St.append("\nKey=" + key + " -- num:" + nb_of_links + "\n");//$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ // Replace the string by index // Add a '+'separator only for more than one links to save space // for (int i = 0; i < nb_of_links; i++) { Link lnk = (Link) in_links.elementAt(i); St.append("\tValue=" + lnk.getURL() + "[" + lnk.getOccurrences() + "]");//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ } System.out.println(St.toString()); } } System.out.println("************************************************\n\n\n\n************************************\n"); //$NON-NLS-1$ } public Vector getInLinks(String filePath) { return (Vector) inLinksTable.get(filePath); } public void getInLinks(String filePath, Vector vectInLinks) { if (inLinksTable != null) { dump(); Vector in_links = (Vector) inLinksTable.get(filePath); if (in_links != null) { for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) ((Link) in_links.elementAt(i)).clone(); vectInLinks.addElement(inlnk); } } } } public Hashtable getAnchorsTable() { return anchorsTable; } /** * Returns the file used to store ServerContextRoot for the project. */ public static File getPreviousSCRFile(IProject project) { return new Path(J2EEPlugin.getDefault().getStateLocation().toString() + File.separator + project.getName() + File.separator + LINK_SERVERCONTEXTROOT_FILE_NAME).toFile(); } /** * Returns the file used to store the state of the link relations for the project. * * @return java.io.File The state file * @param project * org.eclipse.core.resources.IProject The project to get the state file for. */ private File getStateFile(IProject project) { return new Path(J2EEPlugin.getDefault().getStateLocation().toString() + File.separator + project.getName() + File.separator + LINK_STATE_FILE_NAME).toFile(); } public boolean hasInLinkEntry(String path) { return inLinksTable.containsKey(path); } /** * Run through all missing-file (-) RD entries to see if any of them closely match the path to * this class. Return all of the matches. */ public Vector getPossibleMissingEndingMatches(IPath classPath) { Vector v = new Vector(); String match = classPath.lastSegment(); match = match.substring(0, match.length() - 6); // length minus ".class" String classPathStr = classPath.toString(); String matchingClassPath = classPathStr.toString().substring(0, classPathStr.length() - 6); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String path = (String) aenum.nextElement(); // check if path ends with the class name that has been added/removed if (path.startsWith(LINK_MISSING_FILE) && path.endsWith(match)) { // OK: simple match found; now let's match with finer granularity. // Take path and put it into a form where we can check if it is a // close match to the class that has changed: // /Proj/Web Content/com.acme.Foo --> com/acme/Foo String linkPath; int index = path.lastIndexOf(IPath.SEPARATOR); if (index != -1 && index < path.length() - 1) { linkPath = path.substring(index + 1); } else { linkPath = path; } String closeMatch = linkPath.replace('.', IPath.SEPARATOR); if (matchingClassPath.endsWith(closeMatch)) { Vector in_links = (Vector) inLinksTable.get(path); String nonMissingPath = path.substring(1, path.length()); changeInLink(nonMissingPath, false); if (in_links != null) { for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); v.add(url); } } } } } return v; } /** * Run through all existing RD entries to see if any of them closely match the path to this * class. Return all of the matches. */ public Vector getPossibleExistingEndingMatches(IPath classPath) { Vector v = new Vector(); String match = classPath.lastSegment(); match = match.substring(0, match.length() - 6); // length minus ".class" String classPathStr = classPath.toString(); String matchingClassPath = classPathStr.toString().substring(0, classPathStr.length() - 6); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String path = (String) aenum.nextElement(); // check if path ends with the class name that has been added/removed if (path.endsWith(match) && !path.startsWith(LINK_MISSING_FILE)) { // OK: simple match found; now let's match with finer granularity. // Take path and put it into a form where we can check if it is a // close match to the class that has changed: // /Proj/Web Content/com.acme.Foo --> com/acme/Foo String linkPath; int index = path.lastIndexOf(IPath.SEPARATOR); if (index != -1 && index < path.length() - 1) { linkPath = path.substring(index + 1); } else { linkPath = path; } String closeMatch = linkPath.replace('.', IPath.SEPARATOR); if (matchingClassPath.endsWith(closeMatch)) { Vector in_links = (Vector) inLinksTable.get(path); changeInLink(path, true); if (in_links != null) { for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); v.add(url); } } } } } return v; } /** * Run through all existing RD entries to see if any of them closely match the path to this * class. Remove the inlinks for all the matches. */ public void removeInLinksPossibleExistingEndingMatches(IPath classPath) { String match = classPath.lastSegment(); match = match.substring(0, match.length() - 6); // length minus ".class" String classPathStr = classPath.toString(); String matchingClassPath = classPathStr.toString().substring(0, classPathStr.length() - 6); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String path = (String) aenum.nextElement(); if (path.endsWith(match) && !path.startsWith(LINK_MISSING_FILE)) { // OK: simple match found; now let's match with finer granularity. // Take path and put it into a form where we can check if it is a // close match to the class that has changed: // /Proj/Web Content/com.acme.Foo --> com/acme/Foo String linkPath; int index = path.lastIndexOf(IPath.SEPARATOR); if (index != -1 && index < path.length() - 1) { linkPath = path.substring(index + 1); } else { linkPath = path; } String closeMatch = linkPath.replace('.', IPath.SEPARATOR); if (matchingClassPath.endsWith(closeMatch)) { removeInLinks(path); } } } } /** * Initialize links tables */ public void initialize() { inLinksTable = new Hashtable(INIT_HASH_TABLE_SIZE); anchorsTable = new Hashtable(INIT_ANCHORS_HASH_TABLE_SIZE); } /** * Initialize links tables */ public void initializeAnchors() { anchorsTable = new Hashtable(INIT_ANCHORS_HASH_TABLE_SIZE); } /** * Initialize links tables */ public void initializeInLinks() { inLinksTable = new Hashtable(INIT_HASH_TABLE_SIZE); } /** * Return true if the file to restore data from existed and was successfully read. * * @return boolean */ public boolean isFileOk() { return fileOk; } public boolean isInitialized() { return (inLinksTable != null); } public void newInLinkEntry(String path) { if (!inLinksTable.containsKey(path)) inLinksTable.put(path, new Vector()); } public void removeInLinks(String file_path) { // // Iterate through the fLinksTable to remove all in-links references // for file_path // for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String key = (String) aenum.nextElement(); Vector in_links = (Vector) inLinksTable.get(key); for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); if (url.compareTo(file_path) == 0) { in_links.removeElementAt(i); break; } // // Remove the entry in the fLinksTable if the in-link // of the file is not in the workbench and an orphan link // otherwise update the in-links fLinksTable // } if (in_links.isEmpty() && key.startsWith(LINK_MISSING_FILE)) { inLinksTable.remove(key); } } } /** * Iterate through the fLinksTable to return all out-links references for file_path * * @param file_path * @return */ public List getOutLinks(String file_path) { ArrayList list = new ArrayList(); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String key = (String) aenum.nextElement(); Vector in_links = (Vector) inLinksTable.get(key); for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); if (url.compareTo(file_path) == 0) { list.add(key); break; } } } return list; } /** * return whether other resources link to this file or not */ public boolean referencedByOtherLinks(String file_path) { // // Iterate through the fLinksTable to remove all in-links references // for file_path // boolean referenced = false; for (Enumeration aenum = inLinksTable.keys(); !referenced && aenum.hasMoreElements();) { String key = (String) aenum.nextElement(); Vector in_links = (Vector) inLinksTable.get(key); for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); if (url.compareTo(file_path) == 0) { referenced = true; break; } } } return referenced; } /* * performs as removeInLinks( String ) ... But for performance reasons, this also additionally * returns a list of all the projects that this file is dependent upon. This is useful to get * this information, and then go to all of those projects' relation data and tell them to * removeInLinks for this file. */ public Collection removeInLinksForProjects(String file_path) { // // Iterate through the fLinksTable to remove all in-links references // for file_path // Hashtable projects = new Hashtable(); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String key = (String) aenum.nextElement(); Vector in_links = (Vector) inLinksTable.get(key); for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); if (url.compareTo(file_path) == 0) { // should be in the form of: /ProjName/.... if (key.length() > 0) { // key could be the filename or the missing filename ("-" + filename) // take this into account and offset the index accordingly int index = 0; int offset = 1; if (key.charAt(0) == '-') { index = key.indexOf(IPath.SEPARATOR, 2); offset = 2; } else { index = key.indexOf(IPath.SEPARATOR, 1); offset = 1; } if (index != -1) { String projName = key.substring(offset, index); projects.put(projName, projName); } } in_links.removeElementAt(i); break; } // // Remove the entry in the fLinksTable if the in-link // of the file is not in the workbench and an orphan link // otherwise update the in-links fLinksTable // } if (in_links.isEmpty() && key.startsWith(LINK_MISSING_FILE)) inLinksTable.remove(key); } return projects.values(); } /** * performs as removeInLinks( String ) ... But for performance reasons, it additionally returns * which projects depend on this file. i.e. any projects that are in this file's list of * in_links */ public Collection removeInLinksAndGetDependentProjects(String file_path) { // // Iterate through the fLinksTable to remove all in-links references // for file_path // Hashtable projects = new Hashtable(); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String key = (String) aenum.nextElement(); Vector in_links = (Vector) inLinksTable.get(key); if (key.equals(RelationData.LINK_MISSING_FILE + file_path)) { int index = -1; for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); if (url.compareTo(file_path) == 0) { index = i; } if (url.length() > 1) { int projindex = url.indexOf(IPath.SEPARATOR, 1); if (projindex != -1) { String projName = url.substring(1, projindex); projects.put(projName, projName); } } } if (index != -1) { in_links.removeElementAt(index); } } else { for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); if (url.compareTo(file_path) == 0) { in_links.removeElementAt(i); break; } // // Remove the entry in the fLinksTable if the in-link // of the file is not in the workbench and an orphan link // otherwise update the in-links fLinksTable // } } if (in_links.isEmpty() && key.startsWith(LINK_MISSING_FILE)) { inLinksTable.remove(key); } } return projects.values(); } /** * remove all references to a specific inLink. When removeOrphan is true the inLink entry is * removed as well, when there are no more refereces to it */ public void removeInLinks(String inLinkEntry, String inLinkReference, boolean removeOrphan) { String key = inLinkEntry; Vector in_links = (Vector) inLinksTable.get(key); for (int i = 0; i < in_links.size(); i++) { Link inlnk = (Link) in_links.elementAt(i); String url = inlnk.getURL(); if (url.compareTo(inLinkReference) == 0) { in_links.removeElementAt(i); break; } } // If there are no more references to the inLinkEntry // and the caller wants this orphan deleted then // remove the key from the table if (in_links.isEmpty() && removeOrphan) inLinksTable.remove(key); } /** * Restores this builder's saved state and returns whether it was successful in doing so. */ public boolean restore(IProject project) { if (project != null) { // get the state File stateFile = getStateFile(project); if (stateFile.exists()) { inLinksTable = new Hashtable(INIT_HASH_TABLE_SIZE); // read inLinksTable from stateFile Vector keys = new Vector(); Vector indices = new Vector(); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(stateFile)); String line = null; // while( ((line = reader.readLine()) != null) && !line.startsWith( // ANCHOR_SEPARATOR ) ) while ((line = reader.readLine()) != null) { String buffer = line; // to take into account the possibility of links spanning multiple lines, // keep reading until we find a line that starts with an idicator // that the link is finished (a line beginning w/ LINK_INDEX_SEPARATOR) line = reader.readLine(); while (line != null && !line.startsWith(LINK_INDEX_SEPARATOR)) { buffer = buffer + line; line = reader.readLine(); } // add link string (/MyProj/file.html) keys.addElement(buffer); // add references line (+2/3...) if (line != null) { indices.addElement(line); } else { System.out.println(ProjectSupportResourceHandler.Syntax_Error_in_the_links_UI_); // = "Syntax Error in the links state file" return false; } } // Use this to load anchor information // // Now let's add all of the extra anchor information // if ( line != null && line.startsWith( ANCHOR_SEPARATOR ) ) { // while( (line = reader.readLine()) != null ) // { // String buffer = line; // // // to take into account the possibility of links spanning multiple lines, // // keep reading until we find a line that starts with an idicator // // that the link is finished (a line beginning w/ LINK_INDEX_SEPARATOR) // line = reader.readLine(); // while ( line != null && !line.startsWith( ANCHOR_INDEX_SEPARATOR ) ) { // buffer = buffer + line; // line = reader.readLine(); // } // // // add file and all of its anchors // if ( buffer != null && line != null) // { // anchorsTable.put( buffer, line ); // } // else // { // System.out.println(ResourceHandler.getString("Syntax_Error_in_the_links_UI_")); // //$NON-NLS-1$ = "Syntax Error in the links state file" // return false; // } // } // // } } catch (FileNotFoundException fe) { WebPlugin.logError(fe); } catch (IOException ie) { WebPlugin.logError(ie); } finally { if (reader != null) { try { reader.close(); } catch (IOException ie2) { WebPlugin.logError(ie2); } } } // // Populate the hash inLinksTable with keys (file paths) and values (in links files // paths) // fileOk = true; for (int i = 0; i < keys.size(); i++) { try { String key = (String) keys.elementAt(i); String compacted_indices = (String) indices.elementAt(i); // // Parse the in-links indexes // int size = keys.size(); Vector in_links = new Vector(); if (compacted_indices != LINK_INDEX_SEPARATOR) { // Extract indexes and occurences StringTokenizer st_idx_occ = new StringTokenizer(new String(compacted_indices), LINK_INDEX_SEPARATOR); while (st_idx_occ.hasMoreTokens()) { String idx_occ = new String(st_idx_occ.nextToken()); int pos_occ = idx_occ.indexOf(LINK_OCCURENCE_SEPARATOR); int index; int occurence = 1; if (pos_occ == -1) { index = Integer.valueOf(idx_occ).intValue(); } else { index = Integer.valueOf(idx_occ.substring(0, pos_occ)).intValue(); occurence = Integer.valueOf(idx_occ.substring(pos_occ + 1)).intValue(); } if (index >= 0 && index < size) { Link inlnk = new Link((String) keys.elementAt(index), occurence); in_links.addElement(inlnk); } } } inLinksTable.put(key, in_links); } catch (Exception e) { fileOk = false; } } return fileOk; } return false; } return false; } /** * Saves this builder's state to disk so that it can be restarted in the same state later. */ public void save(IProject project) { File stateFile = getStateFile(project); if (inLinksTable == null) { stateFile.delete(); } else { // Prepare the index vector Vector index_vector = new Vector(inLinksTable.size()); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { index_vector.addElement(aenum.nextElement()); } // write inLinksTable to stateFile try { File parentFolder = stateFile.getParentFile(); if (!parentFolder.exists()) { parentFolder.mkdirs(); } PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(stateFile))); for (Enumeration aenum = inLinksTable.keys(); aenum.hasMoreElements();) { String key = (String) aenum.nextElement(); out.print(key); out.println(); out.print(LINK_INDEX_SEPARATOR); Vector in_links = (Vector) inLinksTable.get(key); int nb_of_links = in_links.size(); // Replace the string by index // Add a '+'separator only for more than one links to save space // Add '/<occurence>' only if occurence > 1 to save space // Link lnk = null; int nb_lnks = 0; if (nb_of_links > 0) { lnk = (Link) in_links.elementAt(0); out.print(index_vector.indexOf(lnk.getURL())); nb_lnks = lnk.getOccurrences(); if (nb_lnks > 1) { out.print(LINK_OCCURENCE_SEPARATOR); out.print(nb_lnks); } for (int i = 1; i < nb_of_links; i++) { out.print(LINK_INDEX_SEPARATOR); lnk = (Link) in_links.elementAt(i); out.print(index_vector.indexOf(lnk.getURL())); nb_lnks = lnk.getOccurrences(); if (nb_lnks > 1) { out.print(LINK_OCCURENCE_SEPARATOR); out.print(nb_lnks); } } } out.println(); } /* * use this to save out anchor information // * ############################################ if ( !anchorsTable.isEmpty() ) { * out.println( ANCHOR_SEPARATOR ); } for (Enumeration enum = anchorsTable.keys(); * enum.hasMoreElements();) { String key = (String) enum.nextElement(); * out.print(key); out.println(); //out.print(ANCHOR_INDEX_SEPARATOR); out.println( * anchorsTable.get(key) ); } */ out.flush(); out.close(); } catch (IOException e) { WebPlugin.logError(ProjectSupportResourceHandler.Error_while_saving_links_s_EXC_); // = "Error while saving links state file" } } } /** * Insert the method's description here. Creation date: (3/21/2001 1:45:58 PM) * * @param newFileOk * boolean */ void setFileOk(boolean newFileOk) { fileOk = newFileOk; } }