| /******************************************************************************* |
| * 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; |
| |
| |
| /** |
| * 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 |
| */ |
| 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; |
| } |
| |
| 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$ |
| } |
| org.eclipse.jem.util.logger.proxy.Logger.getLogger().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) |
| if (buffer != null) { |
| 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_); //$NON-NLS-1$ = "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) { |
| org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(fe); |
| } catch (IOException ie) { |
| org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ie); |
| } finally { |
| if (reader != null) { |
| try { |
| reader.close(); |
| } catch (IOException ie2) { |
| org.eclipse.jem.util.logger.proxy.Logger.getLogger().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) { |
| org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ProjectSupportResourceHandler.Error_while_saving_links_s_EXC_); //$NON-NLS-1$ = "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; |
| } |
| } |