/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * 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: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ package org.reuseware.sokan.index.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; import org.reuseware.sokan.ID; import org.reuseware.sokan.IndexRow; import org.reuseware.sokan.index.SokanIndexPlugin; import org.reuseware.sokan.index.emodeler.DefaultEModeler; import org.reuseware.sokan.index.emodeler.EModeler; import org.reuseware.sokan.index.indexer.Indexer; import org.reuseware.sokan.index.indexer.IndexerConfiguration; /** * Common collection of utility methods used in Sokan. */ public final class CoreUtil { private CoreUtil() { } private static List<IConfigurationElement> findExtensionConfigs( String extensionPoint, String extensionName) { if (!Platform.isRunning()) { return Collections.emptyList(); } IConfigurationElement[] config = Platform.getExtensionRegistry() .getConfigurationElementsFor(extensionPoint); List<IConfigurationElement> back = new ArrayList<IConfigurationElement>( config.length); for (IConfigurationElement confElem : config) { if (confElem.getName().equals(extensionName)) { back.add(confElem); } } return back; } /** * @return all registered indexers. */ public static List<IndexerConfiguration> findIndexer() { List<IConfigurationElement> configs = findExtensionConfigs( SokanConst.EXP_INDEX_ID, SokanConst.EXT_INDEXER); List<IndexerConfiguration> allConfigs = new ArrayList<IndexerConfiguration>(); for (IConfigurationElement elem : configs) { String id = elem.getAttribute("id"); Indexer indexer = null; try { indexer = (Indexer) elem.createExecutableExtension("class"); } catch (CoreException e) { SokanIndexPlugin.logError("Error loading indexer '" + id + "'", e); } List<String> dependencies = new ArrayList<String>(); for (IConfigurationElement childElem : elem.getChildren("dependsOn")) { dependencies.add(childElem.getAttribute("indexerID")); } allConfigs.add(new IndexerConfiguration( indexer, id, dependencies)); } return allConfigs; } /** * @return all registered load options. */ public static Map<String, Object> findLoadOptions() { List<IConfigurationElement> configs = CoreUtil.findExtensionConfigs( SokanConst.EXP_INDEX_ID, SokanConst.EXT_LOAD_OPTION); Map<String, Object> loadOptions = new LinkedHashMap<String, Object>(); for (IConfigurationElement elem : configs) { String key = elem.getAttribute("key"); String valueString = elem.getAttribute("value"); Object value = valueString; if (valueString.trim().toUpperCase().equals("TRUE")) { value = Boolean.TRUE; } if (valueString.trim().toUpperCase().equals("FALSE")) { value = Boolean.FALSE; } loadOptions.put(key, value); } return loadOptions; } /** * @return all registered EModelers. */ public static List<EModeler> findEModelers() { List<EModeler> modelers = new ArrayList<EModeler>(); List<IConfigurationElement> configs = findExtensionConfigs( SokanConst.EXP_INDEX_ID, SokanConst.EXT_EMODELER); for (IConfigurationElement config : configs) { try { modelers.add((EModeler) config.createExecutableExtension("class")); } catch (Exception e) { SokanIndexPlugin.logError("Cannot instantiate EModeler: " + config.getAttribute("class"), e); } } modelers.add(new DefaultEModeler()); return modelers; } /** * Prints the information contained in a row into a * human readable string representation. * * @param row the row * @return the information from the row as string */ public static String print(IndexRow row) { StringBuffer s = new StringBuffer(); if (row == null) { s.append("null\n"); return s.toString(); } s.append("\n"); s.append("*************************\n"); s.append("ID: " + ResourceUtil.idString(row.getArtifactID()) + "\n"); s.append("PhysicalURI: " + row.getPhyURI() + "\n"); s.append("Generated: " + row.isGenerated() + "\n"); String line; Map<String, String> single; single = row.getMetaData().getSingleValueFields(); if (single.size() > 0) { s.append("\n"); s.append("~~~ SingleValueFields ~~~\n"); } for (Entry<String, String> entry : single.entrySet()) { line = entry.getKey() + " :: " + entry.getValue(); s.append(line + "\n"); } Map<String, EList<String>> multi; multi = row.getMetaData().getMultiValueFields(); if (multi.size() > 0) { s.append("\n"); s.append("~~~ MultiValueFields ~~~\n"); } for (Entry<String, EList<String>> entry : multi.entrySet()) { line = entry.getKey() + " :: " + toString(entry.getValue()); s.append(line + "\n"); } s.append("*************************\n"); return s.toString(); } /** * @param listString a string representing a list of strings * @param sep the separator used in the list string * @return the list of strings */ public static List<String> toList(String listString, String sep) { List<String> back = new LinkedList<String>(); if (listString == null || sep == null || listString.equals("") || sep.equals("")) { return back; } if (sep.equals(SokanConst.SEPERATOR)) { sep = "\\" + SokanConst.SEPERATOR; } String[] segments; try { segments = listString.split(sep); } catch (Exception e) { SokanIndexPlugin.logError("", e); return back; } for (String seg : segments) { back.add(seg); } return back; } /** * @param list the list * @return the list as comma separated string */ public static String toString(List<?> list) { if (list == null) { return "null"; } String listStr = ""; for (Object obj : list) { listStr += obj.toString() + ", "; } listStr = trimLastSeperator(listStr, ", "); return listStr; } /** * @param list the list * @param sep the separator * @return the list as string using the given separator */ public static String toListString(List<String> list, String sep) { String back = ""; for (String elem : list) { back += elem + sep; } return CoreUtil.trimLastSeperator(back, sep); } /** * @param arg the string * @return the string with the first character trimmed */ public static String trimFirstChar(String arg) { return arg.substring(1, arg.length()); } /** * @param arg the string * @return the string with the last character trimmed */ public static String trimLastChar(String arg) { return arg.substring(0, arg.length() - 1); } /** * @param arg the string * @param sep the separator used in the string * @return the string with the separator trimmed from the end */ public static String trimLastSeperator(String arg, String sep) { if (arg == null || sep == null || arg.equals("") || sep.equals("")) { return ""; } return arg.substring(0, arg.lastIndexOf(sep)); } /** * @param arg the string * @param suffix the suffix to be trimmed from the string * @return the trimmed string */ public static String trimLastString(String arg, String suffix) { try { return arg.substring(0, arg.length() - suffix.length()); } catch (IndexOutOfBoundsException e) { return arg; } } /** * @return the current time */ public static String now() { Calendar cal = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat(SokanConst.DATE_FORMAT_NOW); return sdf.format(cal.getTime()); } /** * Compares the given collections. * * @param col1 collection 1 * @param col2 collection 2 * @return comparison result */ public static boolean equal(Collection<?> col1, Collection<?> col2) { int check = trivialCollectionEqual(col1, col2); switch (check) { case -1: return false; case 1: return true; default: //nothing } //TODO #1469: does not work if same element is contained twice boolean contains; for (Object eObj : col1) { contains = false; for (Object aObj : col2) { if (eObj.equals(aObj)) { contains = true; break; } } if (!contains) { return false; } } return true; } private static int trivialCollectionEqual(Collection<?> expected, Collection<?> actual) { if (expected == null && actual == null) { return 1; } if (expected == null && actual != null) { return -1; } if (actual == null && expected != null) { return -1; } if (expected == null || actual == null) { return -1; } if (expected.size() != actual.size()) { return -1; } if (expected.size() == 0 && actual.size() == 0) { return 1; } return 0; } /** * Produces an error about a cycle in the dependencies between the * given artifacts. * * @param artifactID ID of the artifact of concern * @param cycles IDs of all artifacts involved in the cycle */ public static void cycleWarning(ID artifactID, List<List<ID>> cycles) { if (artifactID == null || cycles == null) { return; } StringBuffer message = new StringBuffer(); message.append("ERROR! Artifact with following " + "id is part of a cycle: " + ResourceUtil.idString(artifactID) + "\n"); message.append("Artifacts involved: "); String cycleStr = ""; for (List<ID> cycle : cycles) { if (cycle.contains(artifactID)) { for (ID id : cycle) { cycleStr += ResourceUtil.idString(id) + ", "; } } } cycleStr = CoreUtil.trimLastSeperator(cycleStr, ", "); message.append(cycleStr + "\n"); SokanIndexPlugin.logError(message.toString(), null); } /** * Adapts a List to an EList. * * @param <T> type of elements in the list. * @param list the list to adapt * @return the list as EList */ public static <T> EList<T> adapt(List<T> list) { EList<T> eList = new BasicEList<T>(); eList.addAll(list); return eList; } /** * Converts the given time stamp into a date object. * * @param timeStamp the time stamp as string * @return the date object */ public static Date toDate(String timeStamp) { if (timeStamp == null || timeStamp.equals("")) { return null; } SimpleDateFormat sdf = new SimpleDateFormat(SokanConst.DATE_FORMAT_NOW); try { Date date = sdf.parse(timeStamp); return date; } catch (ParseException e) { return null; } } }