| /******************************************************************************* |
| * Copyright (c) 2000, 2016 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.help.ui.internal.views; |
| |
| import java.io.BufferedReader; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.io.Reader; |
| import java.nio.charset.StandardCharsets; |
| import java.util.ArrayList; |
| import java.util.Hashtable; |
| import java.util.Observable; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.help.ui.internal.HelpUIPlugin; |
| import org.eclipse.help.ui.internal.IHelpUIConstants; |
| import org.eclipse.help.ui.internal.Messages; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| public class EngineDescriptorManager extends Observable implements IHelpUIConstants { |
| private ArrayList<EngineDescriptor> descriptors; |
| |
| private EngineTypeDescriptor[] engineTypes; |
| |
| private static final String USER_FILE = "userSearches.xml"; //$NON-NLS-1$ |
| private static final String ATT_ENGINE_TYPE_ID = "engineTypeId"; //$NON-NLS-1$ |
| |
| public static class DescriptorEvent { |
| private EngineDescriptor desc; |
| private int kind; |
| public DescriptorEvent(EngineDescriptor desc, int kind) { |
| this.desc = desc; |
| this.kind = kind; |
| } |
| public EngineDescriptor getDescriptor() { |
| return desc; |
| } |
| public int getKind() { |
| return kind; |
| } |
| } |
| |
| public EngineDescriptorManager() { |
| descriptors = new ArrayList<>(); |
| load(); |
| } |
| |
| public void add(EngineDescriptor desc) { |
| descriptors.add(desc); |
| this.setChanged(); |
| this.notifyObservers(new DescriptorEvent(desc, ADD)); |
| } |
| |
| public void remove(EngineDescriptor desc) { |
| descriptors.remove(desc); |
| this.setChanged(); |
| this.notifyObservers(new DescriptorEvent(desc, REMOVE)); |
| } |
| |
| public void notifyPropertyChange(EngineDescriptor desc) { |
| this.setChanged(); |
| this.notifyObservers(new DescriptorEvent(desc, CHANGE)); |
| } |
| |
| public EngineDescriptor[] getDescriptors() { |
| return descriptors.toArray(new EngineDescriptor[descriptors.size()]); |
| } |
| |
| public EngineDescriptor findEngine(String engineId) { |
| for (int i=0; i<descriptors.size(); i++) { |
| EngineDescriptor desc = descriptors.get(i); |
| if (desc.getId().equals(engineId)) |
| return desc; |
| } |
| return null; |
| } |
| |
| public EngineTypeDescriptor[] getEngineTypes() { |
| return engineTypes; |
| } |
| |
| public void save() { |
| IPath stateLoc = HelpUIPlugin.getDefault().getStateLocation(); |
| String fileName = stateLoc.append(USER_FILE).toOSString(); |
| FileOutputStream fos = null; |
| OutputStreamWriter osw = null; |
| try { |
| fos = new FileOutputStream(fileName); |
| osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); |
| PrintWriter writer = new PrintWriter(osw); |
| writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$ |
| writer.println("<engines>"); //$NON-NLS-1$ |
| for (int i = 0; i < descriptors.size(); i++) { |
| EngineDescriptor desc = descriptors.get(i); |
| if (desc.isUserDefined()) { |
| save(writer, desc); |
| } |
| } |
| writer.println("</engines>"); //$NON-NLS-1$ |
| writer.flush(); |
| } |
| catch (IOException e) { |
| HelpUIPlugin.logError(Messages.EngineDescriptorManager_errorSaving, e); |
| } |
| finally { |
| if (osw!=null) { |
| try { |
| osw.close(); |
| } |
| catch (IOException e) { |
| } |
| } |
| if (fos!=null) { |
| try { |
| fos.close(); |
| } |
| catch (IOException e) { |
| } |
| } |
| } |
| } |
| |
| public void load() { |
| loadFromExtensionRegistry(); |
| IPath stateLoc = HelpUIPlugin.getDefault().getStateLocation(); |
| String fileName = stateLoc.append(USER_FILE).toOSString(); |
| try { |
| load(fileName); |
| } |
| catch (IOException e) { |
| HelpUIPlugin.logError(Messages.EngineDescriptorManager_errorLoading, e); |
| } |
| } |
| |
| private void loadFromExtensionRegistry() { |
| IConfigurationElement[] elements = Platform.getExtensionRegistry() |
| .getConfigurationElementsFor(ENGINE_EXP_ID); |
| Hashtable<String, EngineTypeDescriptor> engineTypes = loadEngineTypes(elements); |
| for (int i = 0; i < elements.length; i++) { |
| IConfigurationElement element = elements[i]; |
| if (element.getName().equals(TAG_ENGINE)) { |
| EngineDescriptor desc = new EngineDescriptor(element); |
| String engineId = desc.getEngineTypeId(); |
| if (engineId != null) { |
| EngineTypeDescriptor etdesc = engineTypes.get(engineId); |
| if (etdesc != null) { |
| desc.setEngineType(etdesc); |
| descriptors.add(desc); |
| } |
| } |
| } |
| } |
| } |
| |
| private Hashtable<String, EngineTypeDescriptor> loadEngineTypes(IConfigurationElement[] elements) { |
| Hashtable<String, EngineTypeDescriptor> result = new Hashtable<>(); |
| ArrayList<EngineTypeDescriptor> list = new ArrayList<>(); |
| for (int i = 0; i < elements.length; i++) { |
| IConfigurationElement element = elements[i]; |
| if (element.getName().equals("engineType")) { //$NON-NLS-1$ |
| EngineTypeDescriptor etdesc = new EngineTypeDescriptor(element); |
| String id = etdesc.getId(); |
| if (id != null) { |
| list.add(etdesc); |
| result.put(etdesc.getId(), etdesc); |
| } |
| } |
| } |
| engineTypes = list.toArray(new EngineTypeDescriptor[list.size()]); |
| return result; |
| } |
| |
| public void load(Reader r) { |
| Document document = null; |
| try { |
| DocumentBuilder parser = DocumentBuilderFactory.newInstance() |
| .newDocumentBuilder(); |
| // parser.setProcessNamespace(true); |
| document = parser.parse(new InputSource(r)); |
| |
| // Strip out any comments first |
| Node root = document.getFirstChild(); |
| while (root.getNodeType() == Node.COMMENT_NODE) { |
| document.removeChild(root); |
| root = document.getFirstChild(); |
| } |
| load(document, (Element) root); |
| } catch (ParserConfigurationException e) { |
| // ignore |
| } catch (IOException e) { |
| // ignore |
| } catch (SAXException e) { |
| // ignore |
| } |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on IDialogSettings. |
| */ |
| public void load(String fileName) throws IOException { |
| File file = new File(fileName); |
| if (!file.exists()) return; |
| FileInputStream stream = new FileInputStream(file); |
| BufferedReader reader = new BufferedReader(new InputStreamReader( |
| stream, StandardCharsets.UTF_8)); |
| load(reader); |
| reader.close(); |
| } |
| |
| private void load(Document doc, Element root) { |
| NodeList engines = root.getElementsByTagName(TAG_ENGINE); |
| for (int i=0; i<engines.getLength(); i++) { |
| Node node = engines.item(i); |
| loadUserEntry(node); |
| } |
| } |
| |
| private void loadUserEntry(Node node) { |
| EngineDescriptor edesc = new EngineDescriptor(this); |
| String id = getAttribute(node, ATT_ID); |
| String engineTypeId = getAttribute(node, ATT_ENGINE_TYPE_ID); |
| EngineTypeDescriptor etdesc = findEngineType(engineTypeId); |
| String label = getAttribute(node, ATT_LABEL); |
| String desc = getDescription(node); |
| if (etdesc == null) |
| return; |
| edesc.setEngineType(etdesc); |
| edesc.setUserDefined(true); |
| edesc.setId(id); |
| edesc.setLabel(label); |
| edesc.setDescription(desc); |
| descriptors.add(edesc); |
| } |
| |
| public String computeNewId(String typeId) { |
| ArrayList<Integer> used = new ArrayList<>(); |
| for (int i=0; i<descriptors.size(); i++) { |
| EngineDescriptor ed = descriptors.get(i); |
| if (!ed.isUserDefined()) continue; |
| String edTypeId = ed.getEngineTypeId(); |
| if (typeId.equals(edTypeId)) { |
| String edId = ed.getId(); |
| int loc = edId.lastIndexOf('.'); |
| if (loc!= -1) { |
| String cvalue = edId.substring(loc+1); |
| int ivalue = Integer.parseInt(cvalue); |
| used.add(new Integer(ivalue)); |
| } |
| } |
| } |
| for (int i=1; i<Integer.MAX_VALUE; i++) { |
| if (!isUsed(i, used)) { |
| return typeId+"."+"user."+i; //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| return typeId; |
| } |
| |
| private boolean isUsed(int value, ArrayList<Integer> used) { |
| for (int i=0; i<used.size(); i++) { |
| Integer iv = used.get(i); |
| if (iv.intValue()==value) |
| return true; |
| } |
| return false; |
| } |
| |
| private String getDescription(Node node) { |
| NodeList list = ((Element)node).getElementsByTagName(TAG_DESC); |
| if (list.getLength()==1) { |
| Node desc = list.item(0); |
| NodeList children = desc.getChildNodes(); |
| for (int i=0; i<children.getLength(); i++) { |
| Node child = children.item(i); |
| if (child.getNodeType()==Node.TEXT_NODE) { |
| String text = child.getNodeValue(); |
| return text.trim(); |
| } |
| } |
| } |
| return null; |
| } |
| |
| private void save(PrintWriter writer, EngineDescriptor desc) { |
| String indent = " "; //$NON-NLS-1$ |
| String attIndent = indent + indent; |
| writer.print(indent); |
| writer.println("<engine "); //$NON-NLS-1$ |
| saveAttribute(writer, attIndent, "id", desc.getId()); //$NON-NLS-1$ |
| saveAttribute(writer, attIndent, ATT_ENGINE_TYPE_ID, desc.getEngineTypeId()); |
| saveAttribute(writer, attIndent, ATT_LABEL, desc.getLabel()); |
| writer.println(">"); //$NON-NLS-1$ |
| saveDescription(writer, indent+indent, desc.getDescription()); |
| writer.print(indent); |
| writer.println("</engine>"); //$NON-NLS-1$ |
| } |
| |
| private String getAttribute(Node node, String name) { |
| Node att = node.getAttributes().getNamedItem(name); |
| if (att!=null) |
| return att.getNodeValue(); |
| return null; |
| } |
| |
| private void saveAttribute(PrintWriter writer, String indent, String name, String value) { |
| if (value==null) |
| return; |
| writer.print(indent); |
| writer.print(name); |
| writer.print("=\""); //$NON-NLS-1$ |
| writer.print(value); |
| writer.println("\""); //$NON-NLS-1$ |
| } |
| private void saveDescription(PrintWriter writer, String indent, String desc) { |
| if (desc==null) |
| return; |
| writer.print(indent); |
| writer.println("<description>"); //$NON-NLS-1$ |
| writer.println(desc); |
| writer.print(indent); |
| writer.println("</description>"); //$NON-NLS-1$ |
| } |
| |
| private EngineTypeDescriptor findEngineType(String id) { |
| if (id == null) |
| return null; |
| for (int i = 0; i < engineTypes.length; i++) { |
| EngineTypeDescriptor etd = engineTypes[i]; |
| if (etd.getId().equals(id)) |
| return etd; |
| } |
| return null; |
| } |
| } |