srcanaapps/apiquerytool/com.nokia.s60tools.apiquery.cache/src/com/nokia/s60tools/apiquery/cache/configuration/CacheEntryStorage.java
changeset 0 a02c979e8dfd
equal deleted inserted replaced
-1:000000000000 0:a02c979e8dfd
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */ 
       
    17 
       
    18 package com.nokia.s60tools.apiquery.cache.configuration;
       
    19 
       
    20 import java.io.BufferedOutputStream;
       
    21 import java.io.File;
       
    22 import java.io.FileOutputStream;
       
    23 import java.io.IOException;
       
    24 import java.util.ArrayList;
       
    25 import java.util.Collection;
       
    26 import java.util.Iterator;
       
    27 import java.util.LinkedHashMap;
       
    28 import java.util.LinkedHashSet;
       
    29 import java.util.Map;
       
    30 import java.util.Set;
       
    31 import java.util.Vector;
       
    32 
       
    33 import org.eclipse.core.runtime.IProgressMonitor;
       
    34 
       
    35 import com.nokia.s60tools.apiquery.cache.plugin.CachePlugin;
       
    36 import com.nokia.s60tools.apiquery.cache.resources.Messages;
       
    37 import com.nokia.s60tools.apiquery.shared.datatypes.APIDetailField;
       
    38 import com.nokia.s60tools.apiquery.shared.datatypes.APIDetails;
       
    39 import com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntry;
       
    40 import com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntryStorage;
       
    41 import com.nokia.s60tools.apiquery.shared.datatypes.config.DuplicateEntryException;
       
    42 import com.nokia.s60tools.apiquery.shared.datatypes.config.EntryNotFoundException;
       
    43 import com.nokia.s60tools.apiquery.shared.datatypes.config.IConfigurationChangedListener;
       
    44 import com.nokia.s60tools.apiquery.shared.exceptions.XMLNotValidException;
       
    45 import com.nokia.s60tools.apiquery.shared.job.JobCancelledByUserException;
       
    46 import com.nokia.s60tools.apiquery.shared.util.console.APIQueryConsole;
       
    47 import com.nokia.s60tools.apiquery.shared.util.xml.XMLElementData;
       
    48 import com.nokia.s60tools.apiquery.shared.util.xml.XMLUtils;
       
    49 import com.nokia.s60tools.sdk.SdkInformation;
       
    50 import com.nokia.s60tools.util.debug.DbgUtility;
       
    51 import com.nokia.s60tools.util.resource.FileUtils;
       
    52 
       
    53 /**
       
    54  * Singleton class that is created on plugin startup, and is kept active as long
       
    55  * as plugin is active.
       
    56  * 
       
    57  * The purpose of this class is to store If Sheet entries configured by user.
       
    58  * 
       
    59  * The format of used XML:
       
    60  * 
       
    61  * <?xml version="1.0" encoding="UTF-8" ?> <entries> <metadata id="<drive>:\<path>\my_api.metaxml"
       
    62  * selected="true" sdkid="<DEVICE ID>" size="665" last_modified="1228305614126" />
       
    63  * <metadata id="<drive2>:\<path>\my_api2.metaxml" selected="false" sdkid="<DEVICE2
       
    64  * ID>" size="802" last_modified="1228305614126" /> </entries>
       
    65  * 
       
    66  */
       
    67 public class CacheEntryStorage extends AbstractEntryStorage {
       
    68 
       
    69 	/**
       
    70 	 * Singleton instance.
       
    71 	 */
       
    72 	static private CacheEntryStorage instance = null;
       
    73 
       
    74 	/**
       
    75 	 * Public Singleton instance accessor.
       
    76 	 * 
       
    77 	 * @return Returns instance of this singleton class-
       
    78 	 */
       
    79 	public static CacheEntryStorage getInstance() {
       
    80 		if (instance == null) {
       
    81 			instance = new CacheEntryStorage();
       
    82 		}
       
    83 		return instance;
       
    84 	}
       
    85 
       
    86 	//
       
    87 	// Variables for creating XML file from server entry data.
       
    88 	//
       
    89 	private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";//$NON-NLS-1$
       
    90 
       
    91 	private static final String XML_ROOT_START_ELEMENT = "<entries>";//$NON-NLS-1$
       
    92 
       
    93 	private static final String XML_ROOT_END_ELEMENT = "</entries>";//$NON-NLS-1$
       
    94 
       
    95 	private static final String XML_ATTRIBUTE_ASSIGNMENT_WITH_QUOTE_START = "=\"";//$NON-NLS-1$
       
    96 
       
    97 	private static final String CARRIAGE_RETURN_AND_NEWLINE = "\r\n";//$NON-NLS-1$
       
    98 
       
    99 	private static final String SINGLE_SPACE = " ";//$NON-NLS-1$
       
   100 
       
   101 	private static final String QUOTE_AND_SINGLE_SPACE = "\" ";//$NON-NLS-1$
       
   102 
       
   103 	private static final String ELEMENT_START_STR = "<";//$NON-NLS-1$
       
   104 
       
   105 	private static final String ELEMENT_END_STR = "/>"; //$NON-NLS-1$
       
   106 
       
   107 	//
       
   108 	// XML element and attribute names used for storing configuration
       
   109 	//	
       
   110 	private static final String METADATA_ELEMENT = "metadata";//$NON-NLS-1$
       
   111 
       
   112 	private static final String ID_ATTRIBUTE = "id";//$NON-NLS-1$
       
   113 
       
   114 	private static final String SDK_ID_ATTRIBUTE = "sdkid";//$NON-NLS-1$
       
   115 
       
   116 	private static final String SIZE_ATTRIBUTE = "size";//$NON-NLS-1$
       
   117 
       
   118 	private static final String SELECTION_ATTRIBUTE = "selected";//$NON-NLS-1$	
       
   119 
       
   120 	private static final String DATE_ATTRIBUTE = "last_modified";//$NON-NLS-1$
       
   121 
       
   122 	private static final String API_NAME = "api_name";//$NON-NLS-1$
       
   123 
       
   124 	private Vector<XMLNotValidException> loadErrors = null;
       
   125 
       
   126 	private boolean isLoaded = false;
       
   127 
       
   128 	/**
       
   129 	 * Private default constructor.
       
   130 	 */
       
   131 	private CacheEntryStorage() {
       
   132 		super();
       
   133 		DbgUtility.println(DbgUtility.PRIORITY_CLASS,
       
   134 				"-- <<create>> --> " + getClass().getName()); //$NON-NLS-1$
       
   135 	}
       
   136 
       
   137 	/*
       
   138 	 * (non-Javadoc)
       
   139 	 * 
       
   140 	 * @see com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntryStorage#save(java.lang.String)
       
   141 	 */
       
   142 	public void save(String destinationFileAbsolutePathName) throws IOException {
       
   143 		// System.out.println("save" + destinationFileAbsolutePathName);
       
   144 
       
   145 		StringBuffer xmlDataBuf = new StringBuffer();
       
   146 
       
   147 		File f = new File(destinationFileAbsolutePathName);
       
   148 		// Deleting possibly old
       
   149 		if (f.exists()) {
       
   150 			if (!f.canWrite()) {
       
   151 				String cannotWriteToFileErrMsg = Messages
       
   152 						.getString("CacheEntry.Destination_File_Is_Write_Protected_ErrMsg") //$NON-NLS-1$
       
   153 						+ destinationFileAbsolutePathName;
       
   154 				APIQueryConsole.getInstance().println(cannotWriteToFileErrMsg,
       
   155 						APIQueryConsole.MSG_ERROR);
       
   156 				throw new RuntimeException(cannotWriteToFileErrMsg);
       
   157 			}
       
   158 			if (!f.delete()) {
       
   159 				String cannotWriteToFileErrMsg = Messages
       
   160 						.getString("CacheEntry.Destination_File_Is_In_Use_ErrMsg") //$NON-NLS-1$
       
   161 						+ destinationFileAbsolutePathName;
       
   162 				APIQueryConsole.getInstance().println(cannotWriteToFileErrMsg,
       
   163 						APIQueryConsole.MSG_ERROR);
       
   164 				throw new RuntimeException(cannotWriteToFileErrMsg);
       
   165 			}
       
   166 		}
       
   167 
       
   168 		FileOutputStream fos = new FileOutputStream(f);
       
   169 
       
   170 		BufferedOutputStream bos = new BufferedOutputStream(fos);
       
   171 
       
   172 		xmlDataBuf.append(XML_HEADER);
       
   173 		xmlDataBuf.append(CARRIAGE_RETURN_AND_NEWLINE);
       
   174 		xmlDataBuf.append(XML_ROOT_START_ELEMENT);
       
   175 		xmlDataBuf.append(CARRIAGE_RETURN_AND_NEWLINE);
       
   176 		Collection<AbstractEntry> entriesColl = getEntries();
       
   177 		// Create <ifheet>...</ifheet> XML -elements from entries
       
   178 		for (AbstractEntry entryBeforeCast : entriesColl) {
       
   179 			CacheEntry entry = (CacheEntry) entryBeforeCast;
       
   180 			xmlDataBuf.append(ELEMENT_START_STR + METADATA_ELEMENT
       
   181 					+ SINGLE_SPACE);
       
   182 			xmlDataBuf.append(ID_ATTRIBUTE
       
   183 					+ XML_ATTRIBUTE_ASSIGNMENT_WITH_QUOTE_START + entry.getId()
       
   184 					+ QUOTE_AND_SINGLE_SPACE);
       
   185 			xmlDataBuf.append(SELECTION_ATTRIBUTE
       
   186 					+ XML_ATTRIBUTE_ASSIGNMENT_WITH_QUOTE_START
       
   187 					+ Boolean.toString(entry.isSelected())
       
   188 					+ QUOTE_AND_SINGLE_SPACE);
       
   189 			xmlDataBuf.append(SDK_ID_ATTRIBUTE
       
   190 					+ XML_ATTRIBUTE_ASSIGNMENT_WITH_QUOTE_START
       
   191 					+ entry.getSDKID() + QUOTE_AND_SINGLE_SPACE);
       
   192 			xmlDataBuf.append(SIZE_ATTRIBUTE
       
   193 					+ XML_ATTRIBUTE_ASSIGNMENT_WITH_QUOTE_START
       
   194 					+ entry.getSize() + QUOTE_AND_SINGLE_SPACE);
       
   195 			xmlDataBuf.append(DATE_ATTRIBUTE
       
   196 					+ XML_ATTRIBUTE_ASSIGNMENT_WITH_QUOTE_START
       
   197 					+ entry.getDate() + QUOTE_AND_SINGLE_SPACE);
       
   198 			xmlDataBuf.append(API_NAME
       
   199 					+ XML_ATTRIBUTE_ASSIGNMENT_WITH_QUOTE_START
       
   200 					+ entry.getAPIName() + QUOTE_AND_SINGLE_SPACE);
       
   201 			//System.out.println("apiname" +entry.getAPIName());
       
   202 			xmlDataBuf.append(ELEMENT_END_STR);
       
   203 			xmlDataBuf.append(CARRIAGE_RETURN_AND_NEWLINE);
       
   204 		}
       
   205 		xmlDataBuf.append(XML_ROOT_END_ELEMENT);
       
   206 		xmlDataBuf.append(CARRIAGE_RETURN_AND_NEWLINE);
       
   207 
       
   208 		// Writing data to file
       
   209 		byte[] writeData = xmlDataBuf.toString().getBytes();
       
   210 		bos.write(writeData, 0, writeData.length);
       
   211 		bos.flush();
       
   212 		bos.close();
       
   213 		fos.close();
       
   214 
       
   215 	}
       
   216 
       
   217 	/*
       
   218 	 * (non-Javadoc)
       
   219 	 * 
       
   220 	 * @see com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntryStorage#load(java.lang.String)
       
   221 	 */
       
   222 	public void load(String storageFilePathName) throws IOException {
       
   223 		//System.out.println("storage file path" + storageFilePathName);
       
   224 
       
   225 		// Setting elements to be parsed
       
   226 		Set<String> elemNameSet = new LinkedHashSet<String>();
       
   227 		elemNameSet.add(METADATA_ELEMENT); // server element
       
   228 		// Setting attributes to be parsed for server element
       
   229 		Map<String, String> attrNameSet = new LinkedHashMap<String, String>();
       
   230 		attrNameSet.put(ID_ATTRIBUTE, ID_ATTRIBUTE);
       
   231 		attrNameSet.put(SELECTION_ATTRIBUTE, SELECTION_ATTRIBUTE);
       
   232 		attrNameSet.put(SDK_ID_ATTRIBUTE, SDK_ID_ATTRIBUTE);
       
   233 		attrNameSet.put(SIZE_ATTRIBUTE, SIZE_ATTRIBUTE);
       
   234 		attrNameSet.put(DATE_ATTRIBUTE, DATE_ATTRIBUTE);
       
   235 		attrNameSet.put(API_NAME, API_NAME);
       
   236 		Map<String, Map<String, String>> attributeMap = new LinkedHashMap<String, Map<String, String>>();
       
   237 		attributeMap.put(METADATA_ELEMENT, attrNameSet);
       
   238 
       
   239 		try {
       
   240 			// Loading XML data into memory
       
   241 			StringBuffer xmlData = FileUtils
       
   242 					.loadDataFromFile(storageFilePathName);
       
   243 			// Parsing elements from the XML data and adding found server
       
   244 			// entries to storage
       
   245 			XMLElementData[] elementArr = XMLUtils.parseXML(xmlData.toString(),
       
   246 					elemNameSet, attributeMap);
       
   247 			ArrayList<CacheEntry> foundEntries = convertElementDataToEntryList(elementArr);
       
   248 			// Removing the old server entries and adding new ones
       
   249 			// When we are really sure that the whole load opearation was
       
   250 			// successful.
       
   251 			entriesMap.clear();
       
   252 			for (AbstractEntry entry : foundEntries) {
       
   253 				// CacheEntry ent = (CacheEntry) entry;
       
   254 
       
   255 				entriesMap.put(entry.getId(), entry);
       
   256 			}
       
   257 
       
   258 		} catch (Exception e) {
       
   259 			e.printStackTrace();
       
   260 			String msg = Messages
       
   261 					.getString("CacheEntry.LoadFailed_Part_1_ErrMsg") + e.getMessage() //$NON-NLS-1$
       
   262 					+ ". " + Messages.getString("CacheEntry.LoadFailed_Part_2_ErrMsg"); //$NON-NLS-1$ //$NON-NLS-2$
       
   263 			APIQueryConsole.getInstance().println(msg,
       
   264 					APIQueryConsole.MSG_ERROR);
       
   265 			File f = new File(storageFilePathName);
       
   266 			if (f.exists()) {
       
   267 				f.delete();
       
   268 			}
       
   269 		}
       
   270 	}
       
   271 
       
   272 	/**
       
   273 	 * Converts element data into server entry list.
       
   274 	 * 
       
   275 	 * @param elementArr
       
   276 	 *            XML Element data to be converted.
       
   277 	 * @return Server entry list.
       
   278 	 */
       
   279 	private ArrayList<CacheEntry> convertElementDataToEntryList(
       
   280 			XMLElementData[] elementArr) {
       
   281 		ArrayList<CacheEntry> foundEntries = new ArrayList<CacheEntry>();
       
   282 
       
   283 		// Temporary data used during attribute fetching
       
   284 		String id = null;
       
   285 		String sdkid = null;
       
   286 		boolean isSelected = false;
       
   287 		String apiName = null;
       
   288 		long size = -1;
       
   289 		long date = -1;
       
   290 
       
   291 		for (int i = 0; i < elementArr.length; i++) {
       
   292 			XMLElementData data = elementArr[i];
       
   293 			Map<String, String> params = data.getAttributes();
       
   294 
       
   295 			try {
       
   296 
       
   297 				id = params.get(ID_ATTRIBUTE);
       
   298 				isSelected = Boolean.parseBoolean(params
       
   299 						.get(SELECTION_ATTRIBUTE));
       
   300 				sdkid = params.get(SDK_ID_ATTRIBUTE);
       
   301 				size = Long.parseLong(params.get(SIZE_ATTRIBUTE));
       
   302 				date = Long.parseLong(params.get(DATE_ATTRIBUTE));
       
   303 				apiName = params.get(API_NAME);
       
   304 				//System.out.println("api name" + apiName);
       
   305 			} catch (Exception e) {
       
   306 				throw new RuntimeException(
       
   307 						Messages
       
   308 								.getString("CacheEntry.Unexpected_Attribute_ErrMsg") + data.getElementName()); //$NON-NLS-1$
       
   309 			}
       
   310 
       
   311 			File file = new File(id);
       
   312 			if (file.exists()) {
       
   313 				String fileName = file.getName();
       
   314 				// Adding an entry
       
   315 				foundEntries.add(new CacheEntry(id, fileName, sdkid,
       
   316 						isSelected, size, date, apiName));
       
   317 			}
       
   318 		}
       
   319 		return foundEntries;
       
   320 	}
       
   321 
       
   322 	/**
       
   323 	 * Get currentry selected SDK ID
       
   324 	 * 
       
   325 	 * @return SDK ID or <code>null</code> if not found.
       
   326 	 */
       
   327 	public String getCurrentlySelectedSDKID() {
       
   328 		for (AbstractEntry entry : getEntries()) {
       
   329 			CacheEntry cacheEntry = (CacheEntry) entry;
       
   330 			if (cacheEntry.getSDKID() != null && cacheEntry.isSelected()) {
       
   331 				return cacheEntry.getSDKID();
       
   332 			}
       
   333 		}
       
   334 		return null;
       
   335 	}
       
   336 
       
   337 	/**
       
   338 	 * Updates an entry to the storage. Additional not recommended possibility
       
   339 	 * to update entry without notifying listeners. It's not recommended to use
       
   340 	 * this, but if used, make sure that listeners is notified afterwards by
       
   341 	 * using
       
   342 	 * {@link AbstractEntryStorage#notifyConfigurationChangeListeners(int)}.
       
   343 	 * 
       
   344 	 * @param entryWithNewData
       
   345 	 *            Entry object containing new data.
       
   346 	 * @throws EntryNotFoundException
       
   347 	 * @param dontNotifyListeners
       
   348 	 *            if <code>true</code> listeners will not be notified.
       
   349 	 */
       
   350 	public void updateEntry(AbstractEntry entryWithNewData,
       
   351 			boolean dontNotifyListeners) throws EntryNotFoundException {
       
   352 
       
   353 		if (dontNotifyListeners) {
       
   354 			AbstractEntry entryWithOldData = (AbstractEntry) entriesMap
       
   355 					.get(entryWithNewData.getId());
       
   356 			if (entryWithOldData == null) {
       
   357 				String nonExistingEntryMsg = Messages
       
   358 						.getString("AbstractEntryStorage.NonExistingEntry_ErrMsg") + entryWithNewData.getId(); //$NON-NLS-1$
       
   359 				throw new EntryNotFoundException(nonExistingEntryMsg);
       
   360 			}
       
   361 			// Updating data fields (which triggers notification to
       
   362 			// configuration change listeners)
       
   363 			entryWithOldData
       
   364 					.updateEntryTypeSpecificDataFields(entryWithNewData);
       
   365 		} else {
       
   366 			updateEntry(entryWithNewData);
       
   367 		}
       
   368 		this.isLoaded = false;
       
   369 
       
   370 	}
       
   371 
       
   372 	/*
       
   373 	 * (non-Javadoc)
       
   374 	 * 
       
   375 	 * @see com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntryStorage#updateEntry(com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntry)
       
   376 	 */
       
   377 	public void updateEntry(AbstractEntry entryWithNewData)
       
   378 			throws EntryNotFoundException {
       
   379 		super.updateEntry(entryWithNewData);
       
   380 		this.isLoaded = false;
       
   381 
       
   382 	}
       
   383 
       
   384 	/**
       
   385 	 * Adds an entry to the storage. Additional not recommended possibility to
       
   386 	 * add entry without notifying listeners. It's not recommended to use this,
       
   387 	 * but if used, make sure that listeners is notified afterwards by using
       
   388 	 * {@link AbstractEntryStorage#notifyConfigurationChangeListeners(int)}.
       
   389 	 * 
       
   390 	 * @param entry
       
   391 	 *            Entry to be added.
       
   392 	 * @param dontNotifyListeners
       
   393 	 *            if <code>true</code> listeners will not be notified.
       
   394 	 * @throws DuplicateEntryException
       
   395 	 */
       
   396 	public void addEntry(AbstractEntry entry, boolean dontNotifyListeners)
       
   397 			throws DuplicateEntryException {
       
   398 
       
   399 		if (!dontNotifyListeners) {
       
   400 			super.addEntry(entry);
       
   401 		} else {
       
   402 			if (entriesMap.get(entry.getId()) != null) {
       
   403 				String duplicateEntriesErrMsg = Messages
       
   404 						.getString("AbstractEntryStorage.Duplicate_ErrMsg"); //$NON-NLS-1$
       
   405 				throw new DuplicateEntryException(duplicateEntriesErrMsg);
       
   406 			}
       
   407 			entriesMap.put(entry.getId(), entry);
       
   408 		}
       
   409 		this.isLoaded = false;
       
   410 	}
       
   411 
       
   412 	/*
       
   413 	 * (non-Javadoc)
       
   414 	 * 
       
   415 	 * @see com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntryStorage#addEntry(com.nokia.s60tools.apiquery.shared.datatypes.config.AbstractEntry)
       
   416 	 */
       
   417 	public void addEntry(AbstractEntry entry) throws DuplicateEntryException {
       
   418 		super.addEntry(entry);
       
   419 		this.isLoaded = false;
       
   420 	}
       
   421 
       
   422 	/**
       
   423 	 * Load all selected entrys to storage. Parsing XML:s for all items, by
       
   424 	 * calling {@link CacheEntry#load()}.
       
   425 	 * 
       
   426 	 * Also {@link CacheEntry#unload()} for entry if not selected.
       
   427 	 * 
       
   428 	 * If want to know if there was some errors, ask it by
       
   429 	 * {@link CacheEntryStorage#isLoadErros()}. If there was errors, ask them
       
   430 	 * by {@link CacheEntryStorage#getLoadErrors()}.
       
   431 	 * 
       
   432 	 * @param monitor
       
   433 	 *            to check for cancellations
       
   434 	 * @param newSelectedSDKInfo
       
   435 	 *            SDK info to be selected
       
   436 	 * @throws JobCancelledByUserException
       
   437 	 *             if canceled by user
       
   438 	 * 
       
   439 	 */
       
   440 
       
   441 	public void selectSDKAndLoadAllSelectedDatasToMemory(
       
   442 			IProgressMonitor monitor, SdkInformation newSelectedSDKInfo)
       
   443 			throws JobCancelledByUserException {
       
   444 		selectSDKAndLoadAllSelectedDatasToMemory(monitor, newSelectedSDKInfo,
       
   445 				true);
       
   446 	}
       
   447 
       
   448 	/**
       
   449 	 * Load all selected entrys to storage. Parsing XML:s for all items, by
       
   450 	 * calling {@link CacheEntry#load()}.
       
   451 	 * 
       
   452 	 * Also {@link CacheEntry#unload()} for entry if not selected.
       
   453 	 * 
       
   454 	 * If want to know if there was some errors, ask it by
       
   455 	 * {@link CacheEntryStorage#isLoadErros()}. If there was errors, ask them
       
   456 	 * by {@link CacheEntryStorage#getLoadErrors()}.
       
   457 	 * 
       
   458 	 * @param monitor
       
   459 	 *            to check for cancellations
       
   460 	 * @param newSelectedSDKInfo
       
   461 	 *            SDK info to be selected
       
   462 	 * @param selectSDK
       
   463 	 *            if newSelectedSDKInfo is to be selected as new selected SDK
       
   464 	 * @throws JobCancelledByUserException
       
   465 	 *             if canceled by user
       
   466 	 * 
       
   467 	 */
       
   468 	private void selectSDKAndLoadAllSelectedDatasToMemory(
       
   469 			IProgressMonitor monitor, SdkInformation newSelectedSDKInfo,
       
   470 			boolean selectSDK) throws JobCancelledByUserException {
       
   471 
       
   472 		// set to data store that all are deselected
       
   473 		Collection<AbstractEntry> entrys = getEntries();
       
   474 
       
   475 		// Store current situation for restoring it in cases of cancel
       
   476 		Set<String> keys = entriesMap.keySet();
       
   477 		Map<String, AbstractEntry> storedEntriesMap = new LinkedHashMap<String, AbstractEntry>(
       
   478 				entriesMap.size());
       
   479 		for (String key : keys) {
       
   480 			CacheEntry ent = (CacheEntry) entriesMap.get(key);
       
   481 			APIDetails det = ent.getAPIDetails();// If details is null, it
       
   482 			// must not be loaded now,
       
   483 			// because of lot of time
       
   484 			// taken
       
   485 			CacheEntry ent_ = new CacheEntry(ent.getId(), ent.getName(), ent
       
   486 					.getSDKID(), ent.isSelected(), ent.getSize(),
       
   487 					ent.getDate(), ent.getAPIName());
       
   488 			ent_.setAPIDetails(det);
       
   489 			storedEntriesMap.put(new String(key), ent_);
       
   490 		}
       
   491 
       
   492 		try {
       
   493 
       
   494 			// select new SDK
       
   495 			if (selectSDK) {
       
   496 				selectNewSDK(monitor, newSelectedSDKInfo, entrys);
       
   497 			}
       
   498 
       
   499 			// For XML validity errors
       
   500 			loadErrors = null;
       
   501 			Vector<CacheEntry> entrysToBeUnloaded = new Vector<CacheEntry>();
       
   502 			// Loading all selected entrys to to memory by using entry.load()
       
   503 			for (AbstractEntry entry : entrys) {
       
   504 				// If canceled, throwing exception and catch will handle data
       
   505 				// restore
       
   506 				if (monitor.isCanceled()) {
       
   507 					throw new JobCancelledByUserException(
       
   508 							Messages
       
   509 									.getString("CacheEntryStorage.JobCanceledByUserMsg"));
       
   510 				}
       
   511 				CacheEntry ce = (CacheEntry) entry;
       
   512 				if (ce.isSelected()) {
       
   513 					try {
       
   514 						ce.load();
       
   515 					} catch (XMLNotValidException e) {
       
   516 						addLoadError(e);
       
   517 					}
       
   518 				}
       
   519 				// If entry is not selected, unloading it from memory.
       
   520 				else {
       
   521 					entrysToBeUnloaded.add(ce);
       
   522 				}
       
   523 			}
       
   524 			// If canceled during operation, we unload entrys just when all is
       
   525 			// loaded, unload does not really take any time.
       
   526 			// So for here cancel wont occur anymore
       
   527 			for (CacheEntry ce : entrysToBeUnloaded) {
       
   528 				ce.unload();
       
   529 			}
       
   530 
       
   531 			this.isLoaded = true;
       
   532 
       
   533 		} catch (JobCancelledByUserException e) {
       
   534 			entriesMap = storedEntriesMap;
       
   535 			throw e;
       
   536 		}
       
   537 	}
       
   538 
       
   539 	/**
       
   540 	 * Sets selected sdk as true and un selects not selected SDK
       
   541 	 * 
       
   542 	 * @param monitor
       
   543 	 * @param newSelectedSDKInfo
       
   544 	 * @param entrys
       
   545 	 * @throws JobCancelledByUserException
       
   546 	 */
       
   547 	private void selectNewSDK(IProgressMonitor monitor,
       
   548 			SdkInformation newSelectedSDKInfo, Collection<AbstractEntry> entrys)
       
   549 			throws JobCancelledByUserException {
       
   550 		for (AbstractEntry entry : entrys) {
       
   551 			if (monitor.isCanceled()) {
       
   552 				// If canceled, throwing exception and catch will handle data
       
   553 				// restore
       
   554 				throw new JobCancelledByUserException(Messages
       
   555 						.getString("CacheEntryStorage.JobCanceledByUserMsg"));
       
   556 			}
       
   557 			CacheEntry ce = (CacheEntry) entry;
       
   558 			if (ce.getSDKID().equalsIgnoreCase(newSelectedSDKInfo.getSdkId())) {
       
   559 				entry.setSelected(true, true);
       
   560 			} else {
       
   561 				ce.setSelected(false, true);
       
   562 			}
       
   563 		}
       
   564 	}
       
   565 
       
   566 	/**
       
   567 	 * Load all selected entrys to storage. Parsing XML:s for all items, by
       
   568 	 * calling {@link CacheEntry#load()}.
       
   569 	 * 
       
   570 	 * Also {@link CacheEntry#unload()} for entry if not selected.
       
   571 	 * 
       
   572 	 * If want to know if there was some errors, ask it by
       
   573 	 * {@link CacheEntryStorage#isLoadErros()}. If there was errors, ask them
       
   574 	 * by {@link CacheEntryStorage#getLoadErrors()}.
       
   575 	 * 
       
   576 	 * @param monitor
       
   577 	 *            to check for cancellations
       
   578 	 * @throws JobCancelledByUserException
       
   579 	 *             if canceled by user
       
   580 	 */
       
   581 	public void loadAllSelectedDatasToMemory(IProgressMonitor monitor)
       
   582 			throws JobCancelledByUserException {
       
   583 
       
   584 		selectSDKAndLoadAllSelectedDatasToMemory(monitor, null, false);
       
   585 
       
   586 	}
       
   587 
       
   588 	/**
       
   589 	 * Check if there was load errors.
       
   590 	 * 
       
   591 	 * @return <code>true</code> if there was load errors <code>false</code>
       
   592 	 *         otherwise.
       
   593 	 */
       
   594 	public boolean isLoadErros() {
       
   595 		return loadErrors != null;
       
   596 	}
       
   597 
       
   598 	/**
       
   599 	 * Get load errors
       
   600 	 * 
       
   601 	 * @return load errors or <code>null</code> if there was no errors on
       
   602 	 *         CacheEntryStorage#loadAllSelectedDatasToMemory().
       
   603 	 */
       
   604 	public Vector<XMLNotValidException> getLoadErrors() {
       
   605 		return loadErrors;
       
   606 	}
       
   607 
       
   608 	/**
       
   609 	 * Adds load error to errors
       
   610 	 * 
       
   611 	 * @param e
       
   612 	 */
       
   613 	private void addLoadError(XMLNotValidException e) {
       
   614 
       
   615 		if (loadErrors == null) {
       
   616 			loadErrors = new Vector<XMLNotValidException>();
       
   617 		}
       
   618 		loadErrors.add(e);
       
   619 
       
   620 	}
       
   621 
       
   622 	/**
       
   623 	 * Removes all selected entrys.
       
   624 	 */
       
   625 	public void removeSelectedEntrys(String currentlySelectedSDKID) {
       
   626 
       
   627 		Collection<AbstractEntry> entrys = getEntries();
       
   628 		Vector<String> ids = new Vector<String>();
       
   629 		for (AbstractEntry aEntry : entrys) {
       
   630 			CacheEntry entry = (CacheEntry) aEntry;
       
   631 			if (entry.isSelected()
       
   632 					|| entry.getSDKID().equals(currentlySelectedSDKID)) {
       
   633 				ids.add(entry.getId());
       
   634 			}
       
   635 
       
   636 		}
       
   637 		for (String id : ids) {
       
   638 			entriesMap.remove(id);
       
   639 		}
       
   640 
       
   641 		notifyConfigurationChangeListeners(IConfigurationChangedListener.ALL_SELECTED_ENTRYS_REMOVED);
       
   642 	}
       
   643 
       
   644 	/**
       
   645 	 * Unloads all entrys
       
   646 	 */
       
   647 	public void unload() {
       
   648 		Collection<AbstractEntry> entrys = getEntries();
       
   649 		// For XML validity errors
       
   650 		loadErrors = null;// Now there are no loads -> no load Errors eather
       
   651 		// Unload all items
       
   652 		for (AbstractEntry entry : entrys) {
       
   653 			CacheEntry ce = (CacheEntry) entry;
       
   654 			ce.unload();
       
   655 		}
       
   656 		this.isLoaded = false;
       
   657 	}
       
   658 
       
   659 	/**
       
   660 	 * Check if source is loaded.
       
   661 	 * 
       
   662 	 * @return <code>true</code> if is loaded, false otherwise
       
   663 	 */
       
   664 	public boolean isLoaded() {
       
   665 		return isLoaded;
       
   666 	}
       
   667 
       
   668 	/**
       
   669 	 * Return the path to xml file.
       
   670 	 * @param sdkID : SDK name as given in metadata_cache_entries.xml file
       
   671 	 * @param APIName : API Name
       
   672 	 * @param headerFile : header file name
       
   673 	 * @return
       
   674 	 */
       
   675 	
       
   676 	public String getID(String sdkID, String APIName, String headerFile) {
       
   677 		// System.out.println("SDK ID" +sdkID + "apiame " + APIName + "
       
   678 		// headerfile : " + headerFile);
       
   679 		try {
       
   680 			//CacheEntryStorage instance = getInstance();
       
   681 			//instance.load(CachePlugin.getconfigFilePath());
       
   682 
       
   683 			Set<String> elemNameSet = new LinkedHashSet<String>();
       
   684 			elemNameSet.add(METADATA_ELEMENT); // server element
       
   685 			// Setting attributes to be parsed for server element
       
   686 			Map<String, String> attrNameSet = new LinkedHashMap<String, String>();
       
   687 			attrNameSet.put(ID_ATTRIBUTE, ID_ATTRIBUTE);
       
   688 			attrNameSet.put(SELECTION_ATTRIBUTE, SELECTION_ATTRIBUTE);
       
   689 			attrNameSet.put(SDK_ID_ATTRIBUTE, SDK_ID_ATTRIBUTE);
       
   690 			attrNameSet.put(SIZE_ATTRIBUTE, SIZE_ATTRIBUTE);
       
   691 			attrNameSet.put(DATE_ATTRIBUTE, DATE_ATTRIBUTE);
       
   692 			attrNameSet.put(API_NAME, API_NAME);
       
   693 			Map<String, Map<String, String>> attributeMap = new LinkedHashMap<String, Map<String, String>>();
       
   694 			attributeMap.put(METADATA_ELEMENT, attrNameSet);
       
   695 
       
   696 			// Loading XML data into memory
       
   697 			StringBuffer xmlData = FileUtils.loadDataFromFile(CachePlugin
       
   698 					.getconfigFilePath());
       
   699 			// Parsing elements from the XML data and adding found server
       
   700 			// entries to storage
       
   701 			XMLElementData[] elementArr = XMLUtils.parseXML(xmlData.toString(),
       
   702 					elemNameSet, attributeMap);
       
   703 			for (int i = 0; i < elementArr.length; i++) {
       
   704 				XMLElementData data = elementArr[i];
       
   705 				Map<String, String> params = data.getAttributes();
       
   706 
       
   707 				if (params.get(API_NAME).equalsIgnoreCase(APIName)
       
   708 						&& params.get(SDK_ID_ATTRIBUTE).equalsIgnoreCase(sdkID)) {
       
   709 					//System.out.println("found");
       
   710 					// serach in the list of avaliable folders
       
   711 					String id = params.get(ID_ATTRIBUTE);
       
   712 					// c:\.....\xyz.xml
       
   713 
       
   714 					String folder = id.substring(0, id.lastIndexOf("\\"))
       
   715 							+ "\\inc";
       
   716 					//System.out.println( "Folder" + folder);
       
   717 
       
   718 					File directory = new File(folder);
       
   719 
       
   720 					if (directory.isDirectory()) { // check to make sure it
       
   721 						// is a directory
       
   722 						String filenames[] = directory.list(); // make array of
       
   723 						// filenames.
       
   724 
       
   725 						for (int j = 0; j < filenames.length; j++) {
       
   726 							if (filenames[j].equalsIgnoreCase(headerFile))
       
   727 								return id;
       
   728 						}
       
   729 
       
   730 					} // is directory
       
   731 
       
   732 				}
       
   733 			} //forloop
       
   734 		} catch (Exception e) {
       
   735 			e.printStackTrace();
       
   736 		}
       
   737 
       
   738 		
       
   739 		 
       
   740 
       
   741 		return null;
       
   742 	}
       
   743 
       
   744 }