Monday, 31 August 2015

Setting up Sonar in Local

Sonar Server Setup
  1. Download the Sonar Server from http://www.sonarqube.org/downloads/
  2. Download and Install MySQL Server and MySQL Workbench.
  3. Go to MySQL Workbench and create a new Schema and name it 'sonar'.
  4. Update the sonar.properties @location to <sonar server location>\conf.
    1. Comment the embedded database and uncomment the following line to use MySQL.
    2. sonar.jdbc.url: jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true
  5. Comment out jdbc.url: jdbc:h2:tcp://localhost:9092/sonar.
  6. Set sonar.jdbc.username with value 'root' and sonar.jdbc.password as empty.
  7. Go to <sonar server location>\bin and locate the folder as per your operating system.
  8. Run StartSonar.bat from the folder.
  9. Verify that your Server is up and running. http://localhost:9000(Default Port)
Sonar Runner Setup
  1. Download the Sonar Runner from http://www.sonarqube.org/downloads/
  2. Update the sonar.runner.properties @location to <sonar runner location>\conf.sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true
Add Project to SONAR
  1. Create a sonar-project.properties file with the following properties
    1. sonar.projectKey='YourProjectKey'(without quotes)
    2. sonar.projectName='YourProjectName'(without quotes)
    3. sonar.projectVersion=5.0
    4. sonar.projectDescription='Project Description'(without quotes)
    5. sonar.sources=(Path to the source code folder of your project)
    6. sonar.language=java
    7. sonar.sourceEncoding=UTF-8
  2. Save the above created properties file to your project folder.
  3. Add the following path in environment variables
    1. <SonarRunnerLocation>/bin
  4. Open CMD, navigate to your project folder where the above created properties file is placed and run sonar-runner command. This will run reports and upon successful execution, the sonar report can be viewed on the browser (http://localhost:9000)

Friday, 14 August 2015

XML Validation against XSD(s) - Code

There any many tools available to validate an XML document against an XSD. These include operating system scripts and tools such as xmllint, XMLTools plugin in NotePad++ and many online validators. Java makes it easy to write such a tool and this post demonstrates a utility created in Java for XML validation.

XML Validation against XSD(s) Utility

This is a small utility created using Java Swing and XML Validations which will help validating an XML File against N number of XSD Files. There are a total of 3 classes written and explained as below.
  1. MyValidationHandler.java - A custom validation class written to print all the errors in the XML document in a specific format.
  2. XMLUtils.java - Utility class to validate the type of files selected before starting validation.
  3. ValidateXML.java - Main class to display the UI and take XML and XSD(s) as input.
MyValidationHandler.java 

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import com.del.main.ValidateXML;

public class MyValidationHandler extends DefaultHandler {

@Override
public void warning(SAXParseException e) throws SAXException {
ValidateXML.exceptions.add(printInfo(e));
}

@Override
public void error(SAXParseException e) throws SAXException {
ValidateXML.exceptions.add(printInfo(e));
}

@Override
public void fatalError(SAXParseException e) throws SAXException {
ValidateXML.exceptions.add(printInfo(e));
}

private String printInfo(SAXParseException e) {

StringBuffer result = new StringBuffer();
result.append("ERROR: " + e.getMessage() + "\n");
result.append("   Line number: " + e.getLineNumber() + "\n");
result.append("   Column number: " + e.getColumnNumber());

return result.toString();
}

}

XMLUtils.java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JFileChooser;

public class XMLUtils {

private static Pattern xmlfileExtnPtrn = Pattern
.compile("([^\\s]+(\\.(?i)(xml))$)");
private static Pattern xsdfileExtnPtrn = Pattern
.compile("([^\\s]+(\\.(?i)(xsd))$)");

public static boolean validateFileExtn(String fileName, String xmlOrxsd) {
Matcher mtch = null;
if ("xml".equals(xmlOrxsd)) {
mtch = xmlfileExtnPtrn.matcher(fileName);
} else if ("xsd".equals(xmlOrxsd)) {
mtch = xsdfileExtnPtrn.matcher(fileName);
} else {
return false;
}
if (mtch.matches()) {
return true;
}
return false;
}

public static String chooseFile(String filePath) {

JFileChooser fileChooser = new JFileChooser(filePath);
int fileResult = fileChooser.showOpenDialog(null);

if (fileResult == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile().getAbsolutePath();
}
return null;
}

}



ValidateXML.java

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.SAXException;

import com.del.utils.XMLUtils;
import com.del.validationHandler.MyValidationHandler;

public class ValidateXML {

public static String filePath = null;
static JLabel errorMessage = new JLabel();
static JTextField xmlFileName = new JTextField();
static List<JTextField> xsdFileNames = new ArrayList<JTextField>();
static List<JButton> xsdBrowseButtons = new ArrayList<JButton>();
static JPanel myPanel = new JPanel();
static JFrame frame = new JFrame("Validate XML Utility");
static List<String> xsdStringFileNames = new ArrayList<String>();
static boolean validate = false;
public static List<String> exceptions = new ArrayList<String>();

public static void main(String[] args) {

filePath = System.getProperty("user.home") + "\\Desktop";
viewUI();
}

public static void validateXml(String xmlFileName,
List<String> xsdFileName) {

exceptions = new ArrayList<String>();

SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
StreamSource[] xsdSources = generateStreamSourcesFromXsdPath(xsdFileName);

try {
Schema schema = schemaFactory.newSchema(xsdSources);

Validator validator = schema.newValidator();
validator.setErrorHandler(new MyValidationHandler());
validator.validate(new StreamSource(new File(xmlFileName)));

} catch (IOException exception) {
JOptionPane.showMessageDialog(null, "ERROR: Unable to validate " + xmlFileName
+ " against XSDs " + xsdFileName + " - " + exception, "Message",
JOptionPane.ERROR_MESSAGE);
} catch (SAXException exception) {
JOptionPane.showMessageDialog(null, "ERROR: Unable to validate " + xmlFileName
+ " against XSDs " + xsdFileName + " - " + exception, "Message",
JOptionPane.ERROR_MESSAGE);
}
}

private static StreamSource[] generateStreamSourcesFromXsdPath(
List<String> xsdFileName) {
List<StreamSource> streamSources = new ArrayList<StreamSource>();
for (String xsdPath : xsdFileName) {
streamSources.add(new StreamSource(xsdPath));
}
return streamSources.toArray(new StreamSource[xsdFileName.size()]);
}

private static void viewUI() {

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

myPanel = new JPanel(new BorderLayout(5, 5));
myPanel.setBorder(new TitledBorder(""));

JPanel plafComponents = new JPanel(new GridLayout(0,2,2,2));
plafComponents.setBorder(new TitledBorder("Change the Look and Feel"));

final UIManager.LookAndFeelInfo[] plafInfos = UIManager
.getInstalledLookAndFeels();
String[] plafNames = new String[plafInfos.length];
for (int ii = 0; ii < plafInfos.length; ii++) {
plafNames[ii] = plafInfos[ii].getName();
}
final JComboBox plafChooser = new JComboBox(plafNames);
plafComponents.add(plafChooser);

final JCheckBox pack = new JCheckBox("Auto-resize on theme changes",
true);
plafComponents.add(pack);

plafChooser.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
int index = plafChooser.getSelectedIndex();
try {
UIManager.setLookAndFeel(plafInfos[index].getClassName());
SwingUtilities.updateComponentTreeUI(frame);
if (pack.isSelected()) {
frame.pack();
frame.setMinimumSize(frame.getSize());
}
} catch (Exception e) {
e.printStackTrace();
}
}
});

myPanel.add(plafComponents, BorderLayout.NORTH);

JPanel dynamicLabels = new JPanel(new BorderLayout(4, 4));
dynamicLabels.setBorder(new TitledBorder("Select Files"));
myPanel.add(dynamicLabels, BorderLayout.CENTER);

final JPanel labels = new JPanel(new GridLayout(0, 1, 2, 2));
labels.setBorder(new TitledBorder(""));

labels.add(new JLabel("XML File :"));
labels.add(xmlFileName);
JButton xmlBrowse = new JButton("Browse");
labels.add(xmlBrowse);

xmlBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
xmlFileName.setText(XMLUtils.chooseFile(filePath));
}
});

JButton addNew = new JButton("Add XSD File");

addNew.addActionListener(new ActionListener() {
private int labelCount = 0;

public void actionPerformed(ActionEvent ae) {
labels.add(new JLabel("XSD File " + ++labelCount + " :"));
xsdFileNames.add(new JTextField());
xsdBrowseButtons.add(new JButton("Browse"));
labels.add(xsdFileNames.get(labelCount - 1));
labels.add(xsdBrowseButtons.get(labelCount - 1));
frame.validate();
frame.pack();

if (null != xsdFileNames && !xsdFileNames.isEmpty())
for (int i = 0; i < xsdFileNames.size(); i++) {
final int j = i;
xsdBrowseButtons.get(i).addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
xsdFileNames.get(j).setText(
XMLUtils.chooseFile(filePath));
}
});
}
}
});

dynamicLabels.add(new JScrollPane(labels), BorderLayout.CENTER);

JButton validateButton = new JButton("Validate XML");
plafComponents.add(validateButton);
plafComponents.add(addNew);
plafComponents.add(errorMessage);
errorMessage.setForeground(Color.RED);

validateButton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

if (xmlFileName.getText().isEmpty()) {
errorMessage.setText("XML File not selected");
errorMessage.setVisible(true);
viewUI();
} else if (null != xmlFileName.getText()
&& !XMLUtils.validateFileExtn(xmlFileName.getText(),
"xml")) {
errorMessage.setText("Invalid XML File selected");
errorMessage.setVisible(true);
viewUI();
} else if (xsdFileNames.isEmpty()) {
errorMessage.setText("XSD File(s) not selected");
errorMessage.setVisible(true);
viewUI();
} else {
for (JTextField xsdFileName : xsdFileNames) {
if (xsdFileName.getText().isEmpty()) {
errorMessage.setText("XSD File not selected");
errorMessage.setVisible(true);
viewUI();
} else if (null != xsdFileName.getText()
&& !XMLUtils.validateFileExtn(
xsdFileName.getText(), "xsd")) {
errorMessage.setText("Invalid XSD File selected");
errorMessage.setVisible(true);
viewUI();
} else {
System.out.println("Files Selected properly");
System.out.println("XML ::" + xmlFileName.getText());
System.out.println("XSD ::" + xsdFileName.getText());
errorMessage.setVisible(false);
validate = true;
}

}
}

if (validate) {
xsdStringFileNames=new ArrayList<String>();
for (JTextField xsdFileName : xsdFileNames) {
xsdStringFileNames.add(xsdFileName.getText());
}
validateXml(xmlFileName.getText(), xsdStringFileNames);
StringBuffer output = new StringBuffer();
if (exceptions.isEmpty()) {
output.append("Validation Completed Successfully");
JOptionPane.showMessageDialog(null, output, "Message",
JOptionPane.PLAIN_MESSAGE);
} else {
for (String excp : exceptions) {
output.append(excp + "\n");
}
JOptionPane.showMessageDialog(null, output, "Message",
JOptionPane.ERROR_MESSAGE);
}

}
}
});

frame.setContentPane(myPanel);
frame.pack();
frame.setLocationRelativeTo(null);
try{
frame.setLocationByPlatform(true);
frame.setMinimumSize(frame.getSize());
}
catch(Throwable t)
{

}
frame.setVisible(true);
}
}

XML Validation against XSD(s) Utility

There any many tools available to validate an XML document against an XSD. These include operating system scripts and tools such as xmllint, XMLTools plugin in NotePad++ and many online validators. Java makes it easy to write such a tool and this post demonstrates a utility created in Java for XML validation.

Download Utility here (Leave a comment with your e-mail Id in case the utility from the link is not downloading or not working as expected. I will send it to your e-mail)

Created a small Java Utility using Swing which can validate an XML Document against one or more XSDs. The technical details and code is provided here.

The First Look


This is the 1st look of the utility when it will be started. I have tried to make it more user friendly. I have also provided an option to change the theme of your utility.

Changing the Look and Feel of the Utility

 Theme of the utility can be changed using the drop-down menu provided.

Adding an XML File(File Chooser)

 To add an XML document, the browse button is already provided. Click on the button to open the file chooser popup(provided by Swing). Navigate to the file and select a valid XML document. In case you select an invalid XML Doc, the utility will not allow you to proceed.

Adding an XSD File(Add XSD Button)

 To add XSD document(s), we have provided an 'Add XSD File' button using which once can add N number of XSD documents against which the XML needs to be validated. Click on the button to populate the XSD File Browse button as per your convenience. Once Browse button is clicked, file chooser popup(provided by Swing) is displayed. Navigate to the file and select a valid XSD document(s). In case you select an invalid XSD Document, the utility will not allow you to proceed.

Field Validations


Once you have selected both the XML and XSD Documents. Click on Validate XML button. Before validating the XML, the utility will validate whether correct files are being provided or not. An appropriate error message will be displayed(as above) in case of the following.
  1. XML File not selected.
  2. Invalid XML File selected.
  3. XSD File not selected.
  4. Invalid XSD File selected.
Validation Output
Validation Success


 If the XML is perfect as per the XSD(s) provided, the above message will be displayed.

Validation Failure

If the XML is not written as per the XSD(s) provided, the above window will be provided which will contain the list of all the errors in the XML Document in the following format.
ERROR : (Exception message being displayed)
  Line Number: (Line Number of the incorrect element)
  Column Number: (Column Number of the incorrect element line)