Skip to content

Commit

Permalink
Merge pull request #69 from PhilippSalvisberg/feature/issue_60_snippets
Browse files Browse the repository at this point in the history
#60 - add snippets for annotations and expectations
  • Loading branch information
PhilippSalvisberg committed Jul 13, 2019
2 parents e8130c6 + 1f124cc commit 031f08c
Show file tree
Hide file tree
Showing 7 changed files with 498 additions and 1 deletion.
32 changes: 31 additions & 1 deletion sqldev/src/main/java/org/utplsql/sqldev/model/XMLTools.xtend
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
*/
package org.utplsql.sqldev.model

import java.io.StringWriter
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
import javax.xml.xpath.XPathConstants
import javax.xml.xpath.XPathFactory
import org.w3c.dom.Node
Expand All @@ -34,4 +39,29 @@ class XMLTools {
val Node node = expr.evaluate(doc, XPathConstants.NODE) as Node
return node
}
}

def void trimWhitespace(Node node) {
val children = node.childNodes
for (i : 0 ..< children.length) {
val child = children.item(i)
if (child.nodeType == Node.TEXT_NODE) {
child.textContent = child.textContent.trim
}
trimWhitespace(child);
}
}

def nodeToString(Node node, String cdataSectionElements) {
node.trimWhitespace
val writer = new StringWriter()
val factory = TransformerFactory.newInstance().newTransformer()
factory.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes")
factory.setOutputProperty(OutputKeys.INDENT, "yes")
factory.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
factory.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, cdataSectionElements)
factory.transform(new DOMSource(node), new StreamResult(writer))
val result = writer.toString()
val fixedResult = result.replaceAll('''<!\[CDATA\[\s*\]\]>''',"")
return fixedResult
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2019 Philipp Salvisberg <philipp.salvisberg@trivadis.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.utplsql.sqldev.snippet

import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.io.InputStreamReader
import java.io.StringReader
import java.nio.charset.Charset
import java.nio.file.Files
import java.nio.file.Paths
import java.util.stream.Collectors
import javax.xml.parsers.DocumentBuilderFactory
import oracle.dbtools.util.Resource
import org.utplsql.sqldev.model.XMLTools
import org.xml.sax.InputSource

class SnippetMerger {
val extension XMLTools xmlTools = new XMLTools
File userSnippetsFile
String utplsqlSnippets

def getUtplsqlSnippetsAsString() throws IOException {
val stream = class.getResourceAsStream("/org/utplsql/sqldev/resources/UtplsqlSnippets.xml")
val reader = new BufferedReader(new InputStreamReader(stream, Charset.defaultCharset))
return reader.lines.collect(Collectors.joining(System.lineSeparator))
}

new() {
// works in SQL Developer only, otherwise a ExceptionInInitializerError is thrown
this (new File(Resource.RAPTOR_USER.absolutePath + File.separator + "UserSnippets.xml"))
}

new(File file) {
utplsqlSnippets = utplsqlSnippetsAsString
userSnippetsFile = file
}

def merge() {
var String result
if (userSnippetsFile.exists) {
// file exists, proper merge required
val userSnippets = new String(Files.readAllBytes(Paths.get(userSnippetsFile.absolutePath)))
val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
val userSnippetsDoc = docBuilder.parse(new InputSource(new StringReader(userSnippets)))
val userSnippetsGroups = userSnippetsDoc.getNodeList('''/snippets/group[not(@category="utPLSQL Annotations" or @category="utPLSQL Expectations")]''')
val utplsqlSnippetsDoc = docBuilder.parse(new InputSource(new StringReader(utplsqlSnippets)))
val utplsqlSnippetsGroups = utplsqlSnippetsDoc.getNodeList('''/snippets/group''')
result = '''
<?xml version = '1.0' encoding = 'UTF-8'?>
<snippets>
«FOR i : 0 ..< userSnippetsGroups.length»
«userSnippetsGroups.item(i).nodeToString("code")»
«ENDFOR»
«FOR i : 0 ..< utplsqlSnippetsGroups.length»
«utplsqlSnippetsGroups.item(i).nodeToString("code")»
«ENDFOR»
</snippets>
'''
} else {
// just copy
result = utplsqlSnippets

}
Files.write(Paths.get(userSnippetsFile.absolutePath), result.bytes)
}

def getTemplate() {
return utplsqlSnippets
}

def getFile() {
return userSnippetsFile
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import java.awt.event.ActionListener
import java.util.Map
import javax.swing.JButton
import javax.swing.JCheckBox
import javax.swing.JOptionPane
import javax.swing.JPanel
import javax.swing.JSpinner
import javax.swing.JTabbedPane
Expand All @@ -33,6 +34,7 @@ import oracle.ide.panels.TraversalException
import oracle.javatools.ui.layout.FieldLayoutBuilder
import org.utplsql.sqldev.model.preference.PreferenceModel
import org.utplsql.sqldev.resources.UtplsqlResources
import org.utplsql.sqldev.snippet.SnippetMerger
import org.utplsql.sqldev.ui.common.DirectoryChooser

class PreferencePanel extends DefaultTraversablePanel {
Expand All @@ -43,6 +45,7 @@ class PreferencePanel extends DefaultTraversablePanel {
val JCheckBox clearScreenCheckBox = new JCheckBox
val JCheckBox autoExecuteCheckBox = new JCheckBox
val JCheckBox checkRunUtplsqlTestCheckBox = new JCheckBox
val JButton importSnippetsButton = new JButton(UtplsqlResources.getString("PREF_IMPORT_SNIPPETS_BUTTON_LABEL"))
val JPanel realtimeReporterPanel = new JPanel
val SpinnerNumberModel numberOfRunsInHistoryModel = new SpinnerNumberModel(1, 1, 100, 1);
val JSpinner numberOfRunsInHistorySpinner = new JSpinner(numberOfRunsInHistoryModel);
Expand Down Expand Up @@ -101,6 +104,7 @@ class PreferencePanel extends DefaultTraversablePanel {
runTab.add(
runTab.field.label.withText(UtplsqlResources.getString("PREF_CHECK_RUN_UTPLSQL_TEST_LABEL")).component(
checkRunUtplsqlTestCheckBox))
runTab.addRow(importSnippetsButton)
runTab.addVerticalSpring

// realtime reporter group
Expand Down Expand Up @@ -200,6 +204,13 @@ class PreferencePanel extends DefaultTraversablePanel {
builder.addVerticalField("", tabbedPane)
builder.addVerticalSpring

// register action listener for import snippets button
importSnippetsButton.addActionListener(new ActionListener() {
override actionPerformed(ActionEvent event) {
importSnippets
}
})

// register action listener for create code template button
createCodeTemplatesButton.addActionListener(new ActionListener() {
override actionPerformed(ActionEvent event) {
Expand All @@ -216,6 +227,15 @@ class PreferencePanel extends DefaultTraversablePanel {
})
}

private def importSnippets() {
val snippetMerger = new SnippetMerger
snippetMerger.merge
val file = snippetMerger.file.absolutePath
val message = String.format(UtplsqlResources.getString("PREF_CONFIRM_IMPORT_MESSAGE"), file)
JOptionPane.showMessageDialog(null, message, UtplsqlResources.getString("PREF_CONFIRM_IMPORT_TITLE"),
JOptionPane.INFORMATION_MESSAGE);
}

private def loadCodeTemplates() {
val Map<String, String> map = CodeTemplateUtil.loadFiles()
for (key : map.keySet) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ PREF_RESET_PACKAGE_LABEL=Reset package before running utPLSQL?
PREF_CLEAR_SCREEN_LABEL=Clear script output panel before running utPLSQL?
PREF_AUTO_EXECUTE_LABEL=Execute unit test automatically?
PREF_CHECK_RUN_UTPLSQL_TEST_LABEL=Check availability of menu option?
PREF_IMPORT_SNIPPETS_BUTTON_LABEL=Import Snippets
MENU_REALTIME_REPORTER_LABEL=Realtime Reporter
PREF_NUMBER_OF_RUNS_IN_HISTORY_LABEL=Number of runs in history
PREF_SHOW_DISABLED_COUNTER_LABEL=Show disabled counter?
Expand All @@ -56,6 +57,8 @@ PREF_GENERATE_FILES_LABEL=Generate files?
PREF_OUTPUT_DIRECTORY_LABEL=Output directory
PREF_OUTPUT_DIRECTORY_BUTTON_LABEL=Browse
PREF_DELETE_EXISTING_FILES_LABEL=Delete existing files in output directory?
PREF_CONFIRM_IMPORT_TITLE=Snippets imported
PREF_CONFIRM_IMPORT_MESSAGE=Snippets imported into %s. Please restart SQL Developer for this change to take effect.
MENU_RUN_TEST_LABEL=Run utPLSQL test
MENU_CODE_COVERAGE_LABEL=Code coverage...
MENU_GENERATE_TEST_LABEL=Generate utPLSQL test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ PREF_RESET_PACKAGE_LABEL=Package vor der Ausf
PREF_CLEAR_SCREEN_LABEL=Skriptausgabe-Fenster vor der Ausführung von utPLSQL leeren?
PREF_AUTO_EXECUTE_LABEL=Unit Test automatisch ausführen?
PREF_CHECK_RUN_UTPLSQL_TEST_LABEL=Verfügbarkeit der Menüoption prüfen?
PREF_IMPORT_SNIPPETS_BUTTON_LABEL=Code-Schnipsel importieren
MENU_REALTIME_REPORTER_LABEL=Realtime Reporter
PREF_NUMBER_OF_RUNS_IN_HISTORY_LABEL=Anzahl Ausführungen in der Historie
PREF_SHOW_DISABLED_COUNTER_LABEL=Deaktiviert-Zähler anzeigen?
Expand All @@ -33,6 +34,8 @@ PREF_GENERATE_FILES_LABEL=Dateien generieren?
PREF_OUTPUT_DIRECTORY_LABEL=Ausgabeverzeichnis
PREF_OUTPUT_DIRECTORY_BUTTON_LABEL=Auswählen
PREF_DELETE_EXISTING_FILES_LABEL=Bestehende Dateien im Ausgabeverzeichnis löschen?
PREF_CONFIRM_IMPORT_TITLE=Code-Schnipsel importiert
PREF_CONFIRM_IMPORT_MESSAGE=Code-Schnipsel in %s importiert. Bitte starten Sie den SQL Developer neu, um diese Änderung zu aktivieren.
MENU_RUN_TEST_LABEL=utPLSQL Test ausführen
MENU_CODE_COVERAGE_LABEL=Codeabdeckung...
MENU_GENERATE_TEST_LABEL=utPLSQL Test generieren
Expand Down
Loading

0 comments on commit 031f08c

Please sign in to comment.