core/com.nokia.carbide.cpp.codescanner/src/com/nokia/carbide/cpp/internal/codescanner/kb/CSKbManager.java
changeset 0 fb279309251b
child 127 c937102a5510
equal deleted inserted replaced
-1:000000000000 0:fb279309251b
       
     1 /*
       
     2 * Copyright (c) 2009 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 the License "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.carbide.cpp.internal.codescanner.kb;
       
    19 
       
    20 import java.net.URL;
       
    21 import java.text.MessageFormat;
       
    22 import java.util.ArrayList;
       
    23 import java.util.Dictionary;
       
    24 import java.util.Enumeration;
       
    25 import java.util.Iterator;
       
    26 import java.util.List;
       
    27 
       
    28 import org.eclipse.core.resources.IProject;
       
    29 import org.eclipse.core.runtime.IConfigurationElement;
       
    30 import org.eclipse.core.runtime.IExtension;
       
    31 import org.eclipse.core.runtime.IExtensionPoint;
       
    32 import org.eclipse.core.runtime.IExtensionRegistry;
       
    33 import org.eclipse.core.runtime.IStatus;
       
    34 import org.eclipse.core.runtime.Platform;
       
    35 import org.eclipse.core.runtime.Status;
       
    36 import org.eclipse.emf.common.util.EList;
       
    37 import org.osgi.framework.Bundle;
       
    38 import org.osgi.framework.Version;
       
    39 
       
    40 import com.nokia.carbide.cdt.builder.CarbideBuilderPlugin;
       
    41 import com.nokia.carbide.cdt.builder.project.ICarbideBuildConfiguration;
       
    42 import com.nokia.carbide.cdt.builder.project.ICarbideProjectInfo;
       
    43 import com.nokia.carbide.cpp.internal.codescanner.CSPlugin;
       
    44 import com.nokia.carbide.cpp.internal.codescanner.Messages;
       
    45 import com.nokia.carbide.cpp.internal.codescanner.config.CSConfigSettings;
       
    46 import com.nokia.carbide.cpp.internal.codescanner.gen.CSConfig.CSConfigFactory;
       
    47 import com.nokia.carbide.cpp.internal.codescanner.gen.CSConfig.CustomruleType;
       
    48 import com.nokia.carbide.cpp.internal.codescanner.gen.CSConfig.KeywordType;
       
    49 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.CallType;
       
    50 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.ClassType;
       
    51 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.CommentType;
       
    52 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.FiletypeType;
       
    53 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.InheritanceType;
       
    54 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataBodyType;
       
    55 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataCategoryType;
       
    56 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataKeywordType;
       
    57 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataKeywordsType;
       
    58 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataMetadataType;
       
    59 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataPlatformType;
       
    60 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataRefType;
       
    61 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.KbdataType;
       
    62 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.LocalType;
       
    63 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.MacroType;
       
    64 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.MemberType;
       
    65 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.MessagesType;
       
    66 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.MethodType;
       
    67 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.ParameterType;
       
    68 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.SolutionType;
       
    69 import com.nokia.carbide.cpp.internal.codescanner.gen.Kbdata.SymptomType;
       
    70 import com.nokia.carbide.cpp.internal.codescanner.xml.CSKbdataXMLLoader;
       
    71 import com.nokia.carbide.cpp.sdk.core.ISymbianSDK;
       
    72 
       
    73 /**
       
    74  * A class for handling CodeScanner knowledge base rules.
       
    75  *
       
    76  */
       
    77 public class CSKbManager {
       
    78 
       
    79 	public static final String KBASE_EXTENSION_ID = CSPlugin.PLUGIN_ID + ".rules"; //$NON-NLS-1$
       
    80 	public static final String LOCATION = "location"; //$NON-NLS-1$
       
    81 	public static final String KEYWORDTYPE_BASECLASS = "baseclass"; //$NON-NLS-1$
       
    82 	public static final String KEYWORDTYPE_CALL = "call"; //$NON-NLS-1$
       
    83 	public static final String KEYWORDTYPE_CLASS = "class"; //$NON-NLS-1$
       
    84 	public static final String KEYWORDTYPE_COMMENT = "comment"; //$NON-NLS-1$
       
    85 	public static final String KEYWORDTYPE_GENERIC = "generic"; //$NON-NLS-1$
       
    86 	public static final String KEYWORDTYPE_LOCAL = "local"; //$NON-NLS-1$
       
    87 	public static final String KEYWORDTYPE_MACRO = "macro"; //$NON-NLS-1$
       
    88 	public static final String KEYWORDTYPE_MEMBER = "member"; //$NON-NLS-1$
       
    89 	public static final String KEYWORDTYPE_METHOD = "method"; //$NON-NLS-1$
       
    90 	public static final String KEYWORDTYPE_PARAMETER = "parameter"; //$NON-NLS-1$
       
    91 
       
    92 	// private members
       
    93 	private static final String CATEGORY_ERROR = "error"; //$NON-NLS-1$
       
    94 	private static final String CATEGORY_WARNING = "warning"; //$NON-NLS-1$
       
    95 	private static final String CATEGORY_INFORMATION = "information"; //$NON-NLS-1$
       
    96 	private static final String SEVERITY_HIGH = "high"; //$NON-NLS-1$
       
    97 	private static final String SEVERITY_MEDIUM = "medium"; //$NON-NLS-1$
       
    98 	private static final String SEVERITY_LOW = "low"; //$NON-NLS-1$
       
    99 	private static final String KBDATA_FILE_FILTER = "*.xml"; //$NON-NLS-1$
       
   100 
       
   101 	private ArrayList<CSKbRule> rules;
       
   102 	private ArrayList<CSKbPluginInfo> pluginInfoList;
       
   103 
       
   104 	/**
       
   105 	 * Constructor.
       
   106 	 */
       
   107 	public CSKbManager() {
       
   108 		rules = new ArrayList<CSKbRule>();
       
   109 		pluginInfoList = new ArrayList<CSKbPluginInfo>();
       
   110 	}
       
   111 
       
   112 	/**
       
   113 	 * Add a knowledge base rule.
       
   114 	 * @param rule - knowledge base rule to be added.
       
   115 	 */
       
   116 	public void addRule(CSKbRule rule) {
       
   117 		rules.add(rule);
       
   118 	}
       
   119 
       
   120 	/**
       
   121 	 * Add a collection of knowledge base rules.
       
   122 	 * @param rules - knowledge base rules to be added.
       
   123 	 */
       
   124 	public void addRules(ArrayList<CSKbRule> rules) {
       
   125 		this.rules.addAll(rules);
       
   126 	}
       
   127 
       
   128 	/**
       
   129 	 * Clear all knowledge base rules.
       
   130 	 */
       
   131 	public void clearRules() {
       
   132 		rules.clear();
       
   133 	}
       
   134 
       
   135 	/**
       
   136 	 * Retrieve all knowledge base rules contributed by a plugin.
       
   137 	 * @param pluginID - ID of contributing plugin 
       
   138 	 * @return all knowledge base rules contributed by a plugin
       
   139 	 */
       
   140 	public ArrayList<CSKbRule> getPluginRules(String pluginID) {
       
   141 		if (rules.isEmpty()) {
       
   142 			return null;
       
   143 		}
       
   144 
       
   145 		ArrayList<CSKbRule> pluginRules = new ArrayList<CSKbRule>();
       
   146 		Iterator<CSKbRule> iterator = rules.iterator();
       
   147 		while (iterator.hasNext()) {
       
   148 			CSKbRule rule = iterator.next();
       
   149 			if (rule.getPluginId().equals(pluginID)) {
       
   150 				pluginRules.add(rule);
       
   151 			}
       
   152 		}
       
   153 		return pluginRules;
       
   154 	}
       
   155 
       
   156 	/**
       
   157 	 * Find a knowledge base rule by its name.
       
   158 	 * @param name - name of rule
       
   159 	 * @return knowledge base rule with matching name
       
   160 	 */
       
   161 	public CSKbRule getRule(String name) {
       
   162 		Iterator<CSKbRule> iterator = rules.iterator();
       
   163 		while (iterator.hasNext()) {
       
   164 			CSKbRule rule = iterator.next();
       
   165 			if (rule.getName().equals(name)) {
       
   166 				return rule;
       
   167 			}
       
   168 		}
       
   169 		return null;
       
   170 	}
       
   171 	
       
   172 	/**
       
   173 	 * Retrieve all knowledge base rules.
       
   174 	 * @return all knowledge base rules
       
   175 	 */
       
   176 	public ArrayList<CSKbRule> getRules() {
       
   177 		if (rules.isEmpty()) {
       
   178 			return null;
       
   179 		}
       
   180 		else {
       
   181 			return rules;
       
   182 		}
       
   183 	}
       
   184 
       
   185 	/**
       
   186 	 * Remove a knowledge base rule.
       
   187 	 * @param name - name of the rule to be removed.
       
   188 	 */
       
   189 	public void removeRule(String name) {
       
   190 		CSKbRule found = null;
       
   191 		Iterator<CSKbRule> iterator = rules.iterator();
       
   192 		while (iterator.hasNext()) {
       
   193 			CSKbRule current = iterator.next();
       
   194 			if (current.getName().equals(name)) {
       
   195 				found = current;
       
   196 			}
       
   197 		}
       
   198 
       
   199 		if (found != null) {
       
   200 			rules.remove(found);
       
   201 		}
       
   202 	}
       
   203 
       
   204 	/**
       
   205 	 * Remove a collection of knowledge base rules.
       
   206 	 * @param rules - knowledge base rules to be removed.
       
   207 	 */
       
   208 	public void removeRules(ArrayList<CSKbRule> rules) {
       
   209 		this.rules.removeAll(rules);
       
   210 	}
       
   211 
       
   212 	/**
       
   213 	 * Remove all knowledge base rules contributed by a plugin.
       
   214 	 * @param pluginID - ID of contributing plugin 
       
   215 	 */
       
   216 	public void removeAllPluginRules(String pluginID) {
       
   217 		ArrayList<CSKbRule> pluginRules = getPluginRules(pluginID);
       
   218 		rules.removeAll(pluginRules);
       
   219 	}
       
   220 
       
   221 	/**
       
   222 	 * Copy a collection of knowledge base rules.
       
   223 	 * @param rules - knowledge base rules to be copied.
       
   224 	 */
       
   225 	@SuppressWarnings("unchecked")
       
   226 	public void setRules(ArrayList<CSKbRule> rules) {
       
   227 		Object object = rules.clone();
       
   228 		if (object instanceof ArrayList) {
       
   229 			this.rules = (ArrayList<CSKbRule>)object;
       
   230 		}
       
   231 	}
       
   232 
       
   233 	/**
       
   234 	 * Add knowledge base rules to CodeScanner configuration settings.
       
   235 	 * @param configSettings - configuration settings to be updated.
       
   236 	 */
       
   237 	public void addKBaseRulesToConfigSettings(IProject project, CSConfigSettings configSettings) {
       
   238 		readRulesFromPlugins();
       
   239 		filterRulesforSDKs(getSDKVersions(project));
       
   240 
       
   241 		if (rules.size() > 0) {
       
   242 			EList<CustomruleType> customRuleList = configSettings.getCustomRules().getCustomrule();
       
   243 			customRuleList.clear();
       
   244 			for (Iterator<CSKbRule> ruleIterator = rules.iterator(); ruleIterator.hasNext();) {
       
   245 				CSKbRule kbRule = ruleIterator.next();
       
   246 				CustomruleType customRule = CSConfigFactory.eINSTANCE.createCustomruleType();
       
   247 				customRule.setDescription(kbRule.getDescription());
       
   248 				customRule.setLink(kbRule.getLink());
       
   249 				customRule.setName(kbRule.getName());
       
   250 				customRule.setSeverity(kbRule.getSeverity());
       
   251 				customRule.setTitle(kbRule.getTitle());
       
   252 
       
   253 				EList<KeywordType> keywordList = customRule.getKeyword();
       
   254 				keywordList.clear();
       
   255 				ArrayList<CSKbRuleKeyword> keywords = kbRule.getKeywords();
       
   256 				for (Iterator<CSKbRuleKeyword> keywordIterator = keywords.iterator(); keywordIterator.hasNext();) {
       
   257 					CSKbRuleKeyword kbaseKeyword = keywordIterator.next();
       
   258 					KeywordType customKeyword = CSConfigFactory.eINSTANCE.createKeywordType();
       
   259 					customKeyword.setType(kbaseKeyword.getType());
       
   260 					customKeyword.setValue(kbaseKeyword.getContent());
       
   261 					keywordList.add(customKeyword);
       
   262 				}
       
   263 
       
   264 				EList<String> filetypeList = customRule.getFiletype();
       
   265 				filetypeList.clear();
       
   266 				filetypeList.addAll(kbRule.getFileTypes());
       
   267 				
       
   268 				customRuleList.add(customRule);
       
   269 			}
       
   270 		}
       
   271 	}
       
   272 
       
   273 	/**
       
   274 	 * Retrieve knowledge base rules from contributing plugins using the knowledge base extension.
       
   275 	 */
       
   276 	@SuppressWarnings("unchecked")
       
   277 	public void readRulesFromPlugins() {
       
   278 		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
       
   279 		IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(KBASE_EXTENSION_ID);
       
   280 		IExtension[] extensions = extensionPoint.getExtensions();
       
   281 
       
   282 		for (int i = 0; i < extensions.length; i++) {
       
   283 			IExtension extension = extensions[i];
       
   284 			String pluginID = extension.getNamespaceIdentifier();
       
   285 			Bundle bundle = Platform.getBundle(pluginID);
       
   286 			CSKbPluginInfo kbPluginInfo = new CSKbPluginInfo(pluginID, getBundleVersion(bundle));
       
   287 			pluginInfoList.add(kbPluginInfo);
       
   288 
       
   289 			IConfigurationElement[] elements = extension.getConfigurationElements();
       
   290 			for (int j = 0; j < elements.length; j++) {
       
   291 				String location = elements[j].getAttribute(LOCATION);
       
   292 				Enumeration e = bundle.findEntries(location, KBDATA_FILE_FILTER, false);
       
   293 				while (e!= null && e.hasMoreElements()) {
       
   294 					URL url = (URL)e.nextElement();
       
   295 					if (url != null) {
       
   296 						KbdataType kbdata = loadKbdata(url, pluginID);
       
   297 						if (kbdata != null) {
       
   298 							CSKbRule rule = createKbRule(kbdata);
       
   299 							rule.setPluginId(pluginID);
       
   300 							addRule(rule);
       
   301 						}
       
   302 			        }
       
   303 				}
       
   304 			}
       
   305 		}
       
   306 	}
       
   307 
       
   308 	/**
       
   309 	 * Filter knowledge base rules for a list of SDK versions.
       
   310 	 * @param sdkVersions - list of SDK versions.
       
   311 	 */
       
   312 	private void filterRulesforSDKs(ArrayList<Version> sdkVersions) {
       
   313 		ArrayList<CSKbRule> filteredRules = new ArrayList<CSKbRule>();
       
   314 		for (Iterator<CSKbRule> ruleIterator = rules.iterator(); ruleIterator.hasNext();) {
       
   315 			CSKbRule kbRule = ruleIterator.next();
       
   316 			ArrayList<Version> platforms = kbRule.getPlatforms();
       
   317 			boolean remove = true;
       
   318 			for (Iterator<Version> pfIterator = platforms.iterator(); pfIterator.hasNext();) {
       
   319 				Version platform = pfIterator.next();
       
   320 				if (sdkVersions.contains(platform)) {
       
   321 					remove = false;
       
   322 				}
       
   323 			}
       
   324 			if (remove) {
       
   325 				filteredRules.add(kbRule);
       
   326 			}
       
   327 		}
       
   328 		removeRules(filteredRules);
       
   329 	}
       
   330 
       
   331 	/**
       
   332 	 * Create a knowledge base rule using knowledge base data.
       
   333 	 * @param kbdata - knowledge base data
       
   334 	 * @return a knowledge base rule
       
   335 	 */
       
   336 	private CSKbRule createKbRule(KbdataType kbdata) {
       
   337 		CSKbRule rule = new CSKbRule();
       
   338 		rule.setName(kbdata.getId());
       
   339 		KbdataBodyType kbdataBody = kbdata.getKbdataBody();
       
   340 		EList<KbdataMetadataType> metaDataList = kbdataBody.getKbdataMetadata();
       
   341 		for (Iterator<KbdataMetadataType> iterator1 = metaDataList.iterator(); iterator1.hasNext();) {
       
   342 			KbdataMetadataType metaData = iterator1.next();
       
   343 			KbdataKeywordsType keywordObject = metaData.getKbdataKeywords();
       
   344 			ArrayList<CSKbRuleKeyword> keywords = readKbRuleKeywords(keywordObject);
       
   345 			ArrayList<String> filetypes = readFileTypes(keywordObject);
       
   346 			ArrayList<Version> platforms = readKbdataPlatforms(keywordObject);
       
   347 			rule.setFileTypes(filetypes);
       
   348 			rule.setKeywords(keywords);
       
   349 			rule.setPlatforms(platforms);
       
   350 		}
       
   351 		EList<MessagesType> messageList = kbdataBody.getMessages();
       
   352 		for (Iterator<MessagesType> iterator2 = messageList.iterator(); iterator2.hasNext();) {
       
   353 			MessagesType message = iterator2.next();
       
   354 			String severity = readSeverity(message);
       
   355 			String title = readTitle(message);
       
   356 			String description = readDescription(message);
       
   357 			String link = readLink(message);
       
   358 			rule.setSeverity(severity);
       
   359 			rule.setTitle(title);
       
   360 			rule.setDescription(description);
       
   361 			rule.setLink(link);
       
   362 		}
       
   363 		return rule;
       
   364 	}
       
   365 
       
   366 	
       
   367 	
       
   368 	/**
       
   369 	 * Retrieve bundle version from a given bundle.
       
   370 	 * @param bundle - target bundle
       
   371 	 * @return bundle version
       
   372 	 */
       
   373 	@SuppressWarnings("unchecked")
       
   374 	private String getBundleVersion(Bundle bundle) {
       
   375 		String version = "0.0"; //$NON-NLS-1$
       
   376 		Dictionary bundleHeaders = bundle.getHeaders();
       
   377 		if (bundleHeaders != null) {
       
   378 			version = (String) bundleHeaders.get("Bundle-Version");
       
   379 		}
       
   380 		return version;
       
   381 	}
       
   382 
       
   383 	/**
       
   384 	 * Retrieve SDK versions from the build configurations of a project.
       
   385 	 * @param project - project in question
       
   386 	 * @return list of SDK versions
       
   387 	 */
       
   388 	private ArrayList<Version> getSDKVersions(IProject project) {
       
   389 		ArrayList<Version> sdkVersions = new ArrayList<Version>();
       
   390 		ICarbideProjectInfo projectInfo = CarbideBuilderPlugin.getBuildManager().getProjectInfo(project);
       
   391 		if (projectInfo != null) {
       
   392 			List<ICarbideBuildConfiguration> buildConfigList = projectInfo.getBuildConfigurations();
       
   393 			for (Iterator<ICarbideBuildConfiguration> iterator = buildConfigList.iterator(); iterator.hasNext();) {
       
   394 				ICarbideBuildConfiguration buildConfig = iterator.next();
       
   395 				ISymbianSDK sdk = buildConfig.getSDK();
       
   396 				Version version = sdk.getSDKVersion();
       
   397 				sdkVersions.add(version);
       
   398 			}
       
   399 		}
       
   400 		
       
   401 		return sdkVersions;
       
   402 	}
       
   403 
       
   404 	/**
       
   405 	 * Load data from a knowledge base data file.
       
   406 	 * @param url - url of knowledge base data file
       
   407 	 * @param pluginID - unique ID of the plugin containing the knowledge base data file
       
   408 	 * @return knowledge base data
       
   409 	 */
       
   410 	@SuppressWarnings("static-access")
       
   411 	private KbdataType loadKbdata(URL url, String pluginID) {
       
   412 		KbdataType kbdata = null;
       
   413 		try {
       
   414 			kbdata = CSKbdataXMLLoader.loadKbdata(url);
       
   415 		}
       
   416 		catch (Exception e) {
       
   417 			String format = Messages.getString("KbManager.LoadFailMessage");
       
   418 			String message = MessageFormat.format(format, url.getFile(), pluginID);
       
   419 			IStatus status = new Status(Status.ERROR, CSPlugin.getDefault().PLUGIN_ID, message, e);
       
   420 			CSPlugin.getDefault().getLog().log(status);
       
   421 		}
       
   422 		return kbdata;
       
   423 	}
       
   424 
       
   425 	/**
       
   426 	 * Read the knowledge base keywords.
       
   427 	 * @param keywordObject - knowledge base keyword object
       
   428 	 * @return a list of knowledge base keywords
       
   429 	 */
       
   430 	private ArrayList<CSKbRuleKeyword> readKbRuleKeywords(KbdataKeywordsType keywordObject) {
       
   431 		ArrayList<CSKbRuleKeyword> keywordList = new ArrayList<CSKbRuleKeyword>();
       
   432 		CallType call = keywordObject.getCall();
       
   433 		if (call != null) {
       
   434 			Object object =  call.getMixed().getValue(0);
       
   435 			if (object != null && object instanceof String) {
       
   436 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_CALL));
       
   437 			}
       
   438 		}
       
   439 		ClassType class_ = keywordObject.getClass_();
       
   440 		if (class_ != null) {
       
   441 			Object object =  class_.getMixed().getValue(0);
       
   442 			if (object != null && object instanceof String) {
       
   443 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_CLASS));
       
   444 			}
       
   445 		}
       
   446 		CommentType comment = keywordObject.getComment();
       
   447 		if (comment != null) {
       
   448 			Object object =  comment.getMixed().getValue(0);
       
   449 			if (object != null && object instanceof String) {
       
   450 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_COMMENT));
       
   451 			}
       
   452 		}
       
   453 		InheritanceType inheritance = keywordObject.getInheritance();
       
   454 		if (inheritance != null) {
       
   455 			Object object =  inheritance.getMixed().getValue(0);
       
   456 			if (object != null && object instanceof String) {
       
   457 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_BASECLASS));
       
   458 			}
       
   459 		}
       
   460 		KbdataKeywordType kbdataKeyword = keywordObject.getKbdataKeyword();
       
   461 		if (kbdataKeyword != null) {
       
   462 			Object object =  kbdataKeyword.getMixed().getValue(0);
       
   463 			if (object != null && object instanceof String) {
       
   464 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_GENERIC));
       
   465 			}
       
   466 		}
       
   467 		LocalType local = keywordObject.getLocal();
       
   468 		if (local != null) {
       
   469 			Object object =  local.getMixed().getValue(0);
       
   470 			if (object != null && object instanceof String) {
       
   471 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_LOCAL));
       
   472 			}
       
   473 		}
       
   474 		MacroType macro = keywordObject.getMacro();
       
   475 		if (macro != null) {
       
   476 			Object object =  macro.getMixed().getValue(0);
       
   477 			if (object != null && object instanceof String) {
       
   478 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_MACRO));
       
   479 			}
       
   480 		}
       
   481 		MemberType member = keywordObject.getMember();
       
   482 		if (member != null) {
       
   483 			Object object =  member.getMixed().getValue(0);
       
   484 			if (object != null && object instanceof String) {
       
   485 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_MEMBER));
       
   486 			}
       
   487 		}
       
   488 		MethodType method = keywordObject.getMethod();
       
   489 		if (method != null) {
       
   490 			Object object =  method.getMixed().getValue(0);
       
   491 			if (object != null && object instanceof String) {
       
   492 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_METHOD));
       
   493 			}
       
   494 		}
       
   495 		ParameterType parameter = keywordObject.getParameter();
       
   496 		if (parameter != null) {
       
   497 			Object object =  parameter.getMixed().getValue(0);
       
   498 			if (object != null && object instanceof String) {
       
   499 				keywordList.add(new CSKbRuleKeyword((String)object, KEYWORDTYPE_PARAMETER));
       
   500 			}
       
   501 		}
       
   502 		return keywordList;
       
   503 	}
       
   504 
       
   505 	/**
       
   506 	 * Read the platforms associated with a knowledge base rule.
       
   507 	 * @param keywordObject - knowledge base keyword object
       
   508 	 * @return a list of platforms
       
   509 	 */
       
   510 	private ArrayList<Version> readKbdataPlatforms(KbdataKeywordsType keywordObject) {
       
   511 		EList<KbdataPlatformType> platforms = keywordObject.getKbdataPlatform();
       
   512 		ArrayList<Version> platformList = null;
       
   513 		if (platforms != null) {
       
   514 			platformList = new ArrayList<Version>();
       
   515 			for (Iterator<KbdataPlatformType> iterator = platforms.iterator(); iterator.hasNext();) {
       
   516 				KbdataPlatformType platform = iterator.next();
       
   517 				Object object = platform.getMixed().getValue(0);
       
   518 				if (object != null && object instanceof String) {
       
   519 					try {
       
   520 						Version version = new Version((String)object);
       
   521 						platformList.add(version);
       
   522 					}
       
   523 					catch (IllegalArgumentException e) {
       
   524 						platformList.add(new Version("0.0.0"));
       
   525 					}
       
   526 				}
       
   527 			}
       
   528 			
       
   529 		}
       
   530 		return platformList;
       
   531 	}
       
   532 
       
   533 	/**
       
   534 	 * Read the file types associated with a knowledge base.
       
   535 	 * @param keywordObject - knowledge base keyword object
       
   536 	 * @return a list of file types, or <code>null</code> if none
       
   537 	 */
       
   538 	private ArrayList<String> readFileTypes(KbdataKeywordsType keywordObject) {
       
   539 		EList<FiletypeType> fileTypes = keywordObject.getFiletype();
       
   540 		ArrayList<String> fileTypeList = null;
       
   541 		if (fileTypes != null) {
       
   542 			fileTypeList = new ArrayList<String>();
       
   543 			for (Iterator<FiletypeType> iterator = fileTypes.iterator(); iterator.hasNext();) {
       
   544 				FiletypeType fileType = iterator.next();
       
   545 				Object object = fileType.getMixed().getValue(0);
       
   546 				if (object != null && object instanceof String) {
       
   547 					fileTypeList.add((String)object);
       
   548 				}
       
   549 			}
       
   550 		}
       
   551 		return fileTypeList;
       
   552 	}
       
   553 
       
   554 	/**
       
   555 	 * Read the severity level of a knowledge base rule.
       
   556 	 * @param message - knowledge base message object
       
   557 	 * @return severity level
       
   558 	 */
       
   559 	private String readSeverity(MessagesType message) {
       
   560 		String severity = SEVERITY_LOW;
       
   561 		KbdataCategoryType category = message.getKbdataCategory();
       
   562 		if (category != null) {
       
   563 			Object object = category.getMixed().getValue(0);
       
   564 			if (object != null && object instanceof String) {
       
   565 				String categoryString = (String)object;
       
   566 				if (categoryString.toLowerCase().equals(CATEGORY_ERROR)) {
       
   567 					severity = SEVERITY_HIGH;
       
   568 				}
       
   569 				else if (categoryString.toLowerCase().equals(CATEGORY_WARNING)) {
       
   570 					severity = SEVERITY_MEDIUM;
       
   571 				}
       
   572 				else if (categoryString.toLowerCase().equals(CATEGORY_INFORMATION)) {
       
   573 					severity = SEVERITY_LOW;
       
   574 				}
       
   575 			}
       
   576 		}
       
   577 		return severity;
       
   578 	}
       
   579 
       
   580 	/**
       
   581 	 * Read the message title of a knowledge base rule.
       
   582 	 * @param message - knowledge base message object
       
   583 	 * @return message title
       
   584 	 */
       
   585 	private String readTitle(MessagesType message) {
       
   586 		String title = " ";
       
   587 		SymptomType symptom = message.getSymptom();
       
   588 		if (symptom != null) {
       
   589 			Object object = symptom.getMixed().getValue(0);
       
   590 			if (object != null && object instanceof String) {
       
   591 				title = (String)object;
       
   592 			}
       
   593 		}
       
   594 		return title;
       
   595 	}
       
   596 
       
   597 	/**
       
   598 	 * Read the description of a knowledge base rule.
       
   599 	 * @param message - knowledge base message object
       
   600 	 * @return description
       
   601 	 */
       
   602 	private String readDescription(MessagesType message) {
       
   603 		String description = " ";
       
   604 		SolutionType solution = message.getSolution();
       
   605 		if (solution != null) {
       
   606 			Object object = solution.getMixed().getValue(0);
       
   607 			if (object != null && object instanceof String) {
       
   608 				description = (String)object;
       
   609 			}
       
   610 		}
       
   611 		return description;
       
   612 	}
       
   613 
       
   614 	/**
       
   615 	 * Read the external link of a knowledge base rule.
       
   616 	 * @param message - knowledge base message object
       
   617 	 * @return external link, or <code>null</code> if none
       
   618 	 */
       
   619 	private String readLink(MessagesType message) {
       
   620 		String link = null;
       
   621 		KbdataRefType reference = message.getKbdataRef();
       
   622 		if (reference != null) {
       
   623 			Object object = reference.getHref();
       
   624 			if (object != null && object instanceof String) {
       
   625 				link = (String)object;
       
   626 			}
       
   627 		}
       
   628 		return link;
       
   629 	}
       
   630 }