Changing Java file to Stored procedure - java

I have a java file name E2BXmlParser where I am reading and manipulating the XML data fetched from the database.
Now I am trying to execute the java file using Oracle SQL Developer after changing the file like this
CREATE AND COMPILE JAVA SOURCE NAMED "E2BXmlParser" AS
--(Rest of Code).
And rest of code looks like this--
import oracle.jdbc.*
import oracle.xdb.XMLType;
import oracle.xml.parser.v2.XMLDocument;
import oracle.jdbc.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import java.sql.Connection;
import java.util.*
import javax.xml.xpath.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.io.StringReader;
class Reaction {
}
public class E2BXmlParser {
//variables
public E2BXmlParser(int regReportId, int reportId) {
//connection
}
public static void parseXML(int regReportId, int reportId, int isBlinded, int reportFormid,int pi_is_r3_profile,int pi_max_length,String pi_risk_category) throws SQLException, XPathExpressionException, TransformerException {
//fetching data
}
private static Document getDocumentFromString(String xmlContent) throws Exception {
}
private String getStringByElementName(String tagName, Element element) {
}
private OracleConnection getConnecton() {
//oracle connection
}
private Document getXmlDocumentFromDb(int regReportId, int reportId) {
//fetching and manipulating data
}
private List<Reaction> getReactionIds() {
//logic
}
private void findById(Reaction reaction, String id) {
//xpath for finding nodes
}
private boolean checkNodeExists(Element el, String nodeName) {
NodeList list = el.getElementsByTagName(nodeName);
return list.getLength() > 0;
}
private void updateNode(Reaction reaction, Element el) {
//update xml
}
private void updateXmlInDB(int regReportId, int reportId) throws SQLException {
//update xml in db
}
private void updateDrugNode() {
Element rootElement = document.getDocumentElement();
//logic
}
private void updateDrugEventandDrugRelatedness(int reportFormid) {
//update xml
}
private void updateMedicinalActiveSubstance(int regReportId, int isBlinded, int reportFormid,int pi_is_r3_profile,int pi_max_length,String pi_risk_category) {
//update xml after fetching data and changing in DB
}
private Boolean compareStrings(String strOne, String strTwo) {
//logic
}
private void updateDosageInformation() {
//logic
}
private void updateActiveSubstanceName() {
updating activesubstance using xpath
}
private void RemoveDuplicateActiveSubstance(NodeList activesubstancenameList, List<String> names) {
// logic
}
}
Now it is asking for multiple values(reactions,nodelist,node) that are used in code.
But this is not the case
when I am executing the java file from command line like this
loadjava -user username/password#DBalias -r E2BXmlParser.java
P.S I have to change my E2BXmlParser.java file to E2BXmlParser.sql file so that I can execute it from oracle sql developer.
Please help.

The easiest solution is wrapping all logic of your class into one static method in class. Next you have to publish this method to pl sql.
And publication of static function will be look (more or less) like this.
CREATE PROCEDURE parseXML (regReportId NUMBER, reportId NUMBER, isBlinded NUMBER, reportFormid NUMBER, pi_is_r3_profile NUMBER, pi_max_length NUMBER, pi_risk_category varchar2)
AS LANGUAGE JAVA
NAME 'E2BXmlParser.parseXML(int regReportId, int reportId, int isBlinded, int reportFormid,int pi_is_r3_profile,int pi_max_length,java.lang.String pi_risk_category)';
Note. In plsql you have to use full path to object example String -> java.lang.String
Of course oracle allows to use java class in more object oriented way but this is more complicated.
For more information check this manual. https://docs.oracle.com/cd/E18283_01/java.112/e10588/toc.htm
Chapter 3 (Calling Java Methods in Oracle Database) - for basic solutions.
Chapter 6 (Publishing Java Classes With Call Specifications) - ( paragraph Writing Object Type Call Specifications) - for publishing full java class.

Related

School Java Escape Room Program

I am writing an escape room project for school which has messages such as a greeting, a win message, a loss message, etc. I stored these messages in a text file and then I read the file and store each line into one ArrayList and to access each line by their respective getter method and I use the .get function with their index value. I'm wondering if there is a way to avoid hardcoding the index numbers and on top of that is there a way I can just read the file when the program is run instead of having to make an instance of the class and then for example doing foo.readFile();
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.util.ArrayList;
//package Stage;
public class EscapeRoom{
ArrayList<String> Messages;
String fileName;
private boolean win = false;
public void readFile() throws FileNotFoundException {
Messages = new ArrayList<String>();
fileName = "test.txt";
File file = new File(fileName);
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()){
Messages.add(scanner.nextLine());
}
scanner.close();
}
public void showGreeting(){
System.out.println(Messages.get(0));
}
public void showDirections(){
System.out.println(Messages.get(1));
}
public void showWin() {
System.out.println(Messages.get(2));
}
public void showLoss() {
System.out.println(Messages.get(3));
}
}
This is exactly what a properties file is for. Here is a file I named prompts.properties:
greeting = "hello, welcome to my game"
win = "you win, yay"
loss = "sorry bro, you lose"
directions = "escape with your life!"
Here is your modified program:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class EscapeRoom {
Properties prompts = null;
public void readFile() throws IOException {
prompts = new Properties();
prompts.load(new FileInputStream("prompts.properties"));
}
public void showGreeting() {
System.out.println(prompts.get("greeting"));
}
public void showDirections() {
System.out.println(prompts.get("directions"));
}
public void showWin() {
System.out.println(prompts.get("win"));
}
public void showLoss() {
System.out.println(prompts.get("loss"));
}
}
Basically to get a named key-value pair you want something like a map. Properties are really a special sort of map that understands a file of records that have the format <key> = <value>.
Here is the documentation on Properties and if you decide to roll your own you would implement the same basic thing with a Map.

Spark the best way to load data set in java language

I have a data set like this:
Result categoricF1 categoricF2 categoricF3
N red a apple
P green b banana
....
which I will then convert each element in each column into bit representation
for example:red will be 10000, green will be 01000 and then I will store 10000 in BigInteger array. I will do the same process for each element in dataset
what is the best way for this case to load data? (data frame, data set, RDD)
I need code in Java. Thanks indeed for helping
Spark Dataset are similar to RDDs, however, instead of using Java serialization or Kryo they use a specialized Encoder to serialize the objects for processing or transmitting over the network. While both encoders and standard serialization are responsible for turning an object into bytes, encoders are code generated dynamically and use a format that allows Spark to perform many operations like filtering, sorting and hashing without deserializing the bytes back into an object.
For example, you have a class ClassName which contains all parameters you require in your data.
import java.io.Serializable;
public class ClassName implements Serializable {
private String result;
private String categoricF1;
private String categoricF2;
private String categoricF3;
public String getResult() {
return result;
}
public String getCategoricF1() {
return categoricF1;
}
public String getCategoricF2() {
return categoricF2;
}
public String getCategoricF3() {
return categoricF3;
}
public void setResult(String result) {
this.result = result;
}
public void setCategoricF1(String categoricF1) {
this.categoricF1 = categoricF1;
}
public void setCategoricF2(String categoricF2) {
this.categoricF2 = categoricF2;
}
public void setCategoricF3(String categoricF3) {
this.categoricF3 = categoricF3;
}
}
Then to create Dataset of required data, you can code like this:
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Encoder;
import org.apache.spark.sql.Encoders;
import org.apache.spark.sql.SparkSession;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
SparkSession spark = SparkSession
.builder()
.appName("Java Spark SQL basic example")
.master("local")
.getOrCreate();
// Create an instance of a Bean class
ClassName elem1 = new ClassName();
elem1.setResult("N");
elem1.setCategoricF1("red");
elem1.setCategoricF2("a");
elem1.setCategoricF3("apple");
ClassName elem2 = new ClassName();
elem2.setResult("P");
elem2.setCategoricF1("green");
elem2.setCategoricF2("b");
elem2.setCategoricF3("banana");
List<ClassName> obj = new ArrayList<>();
obj.add(elem1);
obj.add(elem2);
// Encoders are created for Java beans
Encoder<ClassName> classNameEncoder = Encoders.bean(ClassName.class);
Dataset<ClassName> javaBeanDS = spark.createDataset(obj, personEncoder);
javaBeanDS.show();
}
}

CellUtil: Key type in createCell method

I am using the CellUtil class packaged in org.apache.hadoop.hbase to create a Cell object. The function header looks like this:
public static Cell createCell(byte[] row, byte[] family, byte[] qualifier, long timestamp, byte type, byte[] value)
What does the 5th. argument byte type represent? I looked into the KeyValueType class and it refers to an enum called Type with the following definition:
public static enum Type {
Minimum((byte)0),
Put((byte)4),
Delete((byte)8),
DeleteFamilyVersion((byte)10),
DeleteColumn((byte)12),
DeleteFamily((byte)14),
// Maximum is used when searching; you look from maximum on down.
Maximum((byte)255);
private final byte code;
Type(final byte c) {
this.code = c;
}
public byte getCode() {
return this.code;
}
My question is, what has the type minimum, put, etc. got to do with the type of cell I want to create?
Sarin,
Please refer 69.7.6. KeyValue
There are some scenarios in which you will use these enums. For Example, I'm writing coprocessor like below then I will use KeyValue.Type.Put.getCode()
similarly other Enums also can be used like this.
See example co-processor usage below...
package getObserver;
import java.io.IOException;
import java.util.List;
import java.util.NavigableSet;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
public class Observer extends BaseRegionObserver{
private boolean isOewc;
#Override
public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> arg0,
Get arg1, List<Cell> arg2) throws IOException {
NavigableSet<byte[]> qset = arg1.getFamilyMap().get("colfam1".getBytes());
if(qset==null){//do nothing
}else{
String message = "qset.size() = "+String.valueOf(qset.size());
String m = "isOewc = "+String.valueOf(isOewc);
this.isOewc = true;
Cell cell = CellUtil.createCell(
"preGet Row".getBytes(),
m.getBytes(),
message.getBytes(),
System.currentTimeMillis(),
KeyValue.Type.Put.getCode(),
"preGet Value".getBytes());
arg2.add(cell);
}
}
#Override
public void postGetOp(ObserverContext<RegionCoprocessorEnvironment> arg0,
Get arg1, List<Cell> arg2) throws IOException {
String m = "isOewc = "+String.valueOf(isOewc);
Cell cell = CellUtil.createCell(
"postGet Row".getBytes(),
m.getBytes(),
"postGet Qualifier".getBytes(),
System.currentTimeMillis(),
KeyValue.Type.Put.getCode(),
"postGet Value".getBytes());
arg2.add(cell);
}
}
Similarly other below EnumTypes can be used if you don't know which
operation you are going to perform on co-processor event..
programcreek examples clearly explains what is the usage of Put,Delete(prepare key value pairs for mutation) maximum,minimum (for range check). also Co-processor above example uses Put.

Java System Dependence Graph API

From what i read on the Net: PDG or SDG can give me a tree of dependecies i tried with a simple exemple but i have no result
what i did :
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import org.objectweb.asm.tree.analysis.AnalyzerException;
import com.graph.element.Node;
import com.graph.internal.NodeNotFoundException;
import com.graph.sdg.SystemDependenceGraph;;
public class A {
public static void main(String[] args) throws FileNotFoundException, IOException, AnalyzerException, NodeNotFoundException {
SystemDependenceGraph lvSystemDependenceGraph
=new SystemDependenceGraph("C:\\Users\\amina\\workspace\\SDG\\fact","C:\\Users\\amina\\workspace\\SDG\\fact\\bin\\Fact.class");
Iterator<Node> lvIterator =lvSystemDependenceGraph.controlDependenceBFSIterator();
while (lvIterator.hasNext()) {
Node lvNode = lvIterator.next();
}
}
}
class fact :
public class Fact {
public static void main(String[] args) {
int f;
int n;
n=4;
f=1;
while(n!=0){
f=f*n;
n=n-1;
}
System.out.println("f= "+f+" n= "+n);
}
}
when i run class A there is no result
SDG is a java library for analyzing java code. It processes the java sources/byte code, converts into a graph. If you iterate with either BFS or DFS, it gives you series of instruction(code) including the callee method instructions.
In the above example, Class A is iterating over the instructions. Every Node is a instruction there. After retrieving node, you are not printing it so there is no output for the above class.
If you add below line, then it works.
System.out.println("Instruction is " + node.getName());
There are other methods in the Node class like sourceline(getLine()), source is a caller or not (getCaller), what is the instruction type (getType()) etc...

how I can put a dynamic filtered xpage view / repeat control into a hashmap?

Can I easily put the entry values of a filtered view into a hashmap?
I have a repeat control, bound to a view, with a dynamic filter.
The user can change the filter by several djFilteringSelect controls, corresponding to the view columns.
Depending on the selection in the 1st djFilteringSelect, the selection in the next djFilteringSelects should be limited to the possible entries ("similar to the data filter in excel"). At the moment I do this with separate #dbcolumn/#dblookup methods for the djFilteringSelects, but I think it is much better and easier to just fill the view entries values into a hashmap and show the hashmap values in the djFilteringSelect.
I found few threads here with repeat controls and hashmaps, but these examples also build the doc collection separatly, which I wish to avoid.
Thanks for any help,
Uwe
There's a reason why all these examples build their document collections separately. Instead of "the view is in the UI", so I must use it, you might have an easier time to build a bean that serves as the source for your repeat control. A bean data source or a managed bean. This will allow for a use case, where you show 2 filter results (e.g England/London and France/Lyon) in one display, something a filtered view can't do.
Update
If you have a lot of reader/author fields, you want to have a view categorized by them, to populate your "backing bean" - there is lot of performance to gain. Holding a few hundred items in memory isn't a big deal.
There are 2 trains of though: make it generic, so every line in the view ends up as a Collection item (Array, List, Map etc.) or to build dedicated line items with clear names. This trains collide quite often, let me take you to the dedicated train for a moment. :-) So your classes (you need 2) would look like this:
package test;
import java.io.Serializable;
import java.util.Vector;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.NotesException;
import lotus.domino.ViewEntry;
public class Fruit implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String color;
private String shape;
private String taste;
private String unid = null;
public Fruit() {
// default constructor, might not be needed
}
// To make it easy from a view
public Fruit(final ViewEntry ve) {
try {
#SuppressWarnings("rawtypes")
Vector v = ve.getColumnValues();
// 0 would be the user/group/role
this.setName(v.get(1).toString());
this.setColor(v.get(2).toString());
this.setShape(v.get(3).toString());
this.setTaste(v.get(4).toString());
this.unid = ve.getUniversalID();
} catch (NotesException e) {
e.printStackTrace();
}
}
public void save(Database db) throws NotesException {
Document doc;
if (this.unid == null) {
doc = db.createDocument();
} else {
doc = db.getDocumentByUNID(this.unid);
}
doc.replaceItemValue("Color", this.getColor());
// more here
doc.save();
}
public final String getName() {
return this.name;
}
public final void setName(String name) {
this.name = name;
}
public final String getColor() {
return this.color;
}
public final void setColor(String color) {
this.color = color;
}
public final String getShape() {
return this.shape;
}
public final void setShape(String shape) {
this.shape = shape;
}
public final String getTaste() {
return this.taste;
}
public final void setTaste(String taste) {
this.taste = taste;
}
}
That's to hold a line item (using my favourite fruits example). In your code the repeat control variable (or the data table variable) - instead of the view control, would hold one Fruit instance coming from fruitController.getSelectedFruits() (which you can use in EL as fruitController.selectedFruits), so you can bind your columns using varName.color, varname.shape
The class around it looks roughly like:
package test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;
import lotus.domino.Database;
import lotus.domino.NotesException;
import lotus.domino.Session;
import lotus.domino.View;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;
public class FruitController implements Serializable {
private static final long serialVersionUID = 1L;
private static final String FRUIT_VIEW = "(FruitsByUser)";
private final Collection<Fruit> allFruits = new ArrayList<Fruit>();
private final Set<String> colors = new TreeSet<String>();
private final Set<String> shape = new TreeSet<String>();
private final Set<String> taste = new TreeSet<String>();
private String colorFilter = null;
private String tasteFilter = null;
private String shapeFilter = null;
// if you use this controller, you only can use an object data source!
// for a bean you would need an empty controller
public FruitController(final Session s, final Database db) {
this.populateData(s, db);
}
public final String getColorFilter() {
return this.colorFilter;
}
public final String[] getColors() {
return (String[]) this.colors.toArray();
}
public Collection<Fruit> getSelectedFruits() {
Collection<Fruit> result = new ArrayList<Fruit>();
for (Fruit f : this.allFruits) {
if (this.matchesFilter(f)) {
result.add(f);
}
}
return result;
}
public final String[] getShape() {
return (String[]) this.shape.toArray();
}
public final String getShapeFilter() {
return this.shapeFilter;
}
public final String[] getTaste() {
return (String[]) this.taste.toArray();
}
public final String getTasteFilter() {
return this.tasteFilter;
}
public void resetFilters() {
this.setColorFilter(null);
this.setShapeFilter(null);
this.setTasteFilter(null);
}
public final void setColorFilter(String colorFilter) {
this.colorFilter = colorFilter;
}
public final void setShapeFilter(String shapeFilter) {
this.shapeFilter = shapeFilter;
}
public final void setTasteFilter(String tasteFilter) {
this.tasteFilter = tasteFilter;
}
private boolean matchesFilter(Fruit f) {
boolean result = true;
result = ((result == false) ? false : ((this.colorFilter == null || "".equals(this.colorFilter.trim())) ? true
: (this.colorFilter.equals(f.getColor()))));
result = ((result == false) ? false : ((this.tasteFilter == null || "".equals(this.tasteFilter.trim())) ? true
: (this.tasteFilter.equals(f.getTaste()))));
result = ((result == false) ? false : ((this.shapeFilter == null || "".equals(this.shapeFilter.trim())) ? true
: (this.shapeFilter.equals(f.getShape()))));
return result;
}
private void populateData(final Session s, final Database db) {
try {
final View v = db.getView(FRUIT_VIEW);
// You might need to loop a little here to get all the values
final ViewEntryCollection vec = v.getAllEntriesByKey(s.getUserName());
ViewEntry ve = vec.getFirstEntry();
while (ve != null) {
ViewEntry nextVe = vec.getNextEntry(ve);
Fruit f = new Fruit(ve);
this.updateSelectors(f);
this.allFruits.add(f);
ve = nextVe;
nextVe.recycle();
}
vec.recycle();
v.recycle();
} catch (NotesException e) {
// TODO Stacktrace is no error handling
e.printStackTrace();
}
}
private void updateSelectors(Fruit f) {
this.colors.add(f.getColor());
this.shape.add(f.getShape());
this.taste.add(f.getTaste());
}
}
Of course you can make that more sophisticated by filtering the selection values based on the other selections (e.g. after picking a color only offer the shapes that are available in that color). Using the class as object datasource (e.g. fruitController) should be easy. You can bind your dropdowns to fruitController.colorFilter etc. in EL and define the selections in EL as fruitController.Colors.
Update 2
The data source should be an object data source, like this one:
<xp:this.data>
<xe:objectData var="fruitController" ignoreRequestParams="true"
readonly="false" scope="view"
createObject="#{javascript:return new test.FruitController(session, database);}">
</xe:objectData>
</xp:this.data>
For a bean approach you would need to edit the faces-config.xml and change the class to have a parameterless constructor. For the select values you could stick with the toArray() call in your page or better change the class to return an array in the first place. I updated the class above accordingly (so you can still use EL, no need for SSJS).
Now you only need to add a refresh to the repeat in the onChange event of your selects. Since the new values will be send to the object data source (you bound them to colorFilter, shapeFilter, tasteFilter) the refresh will execute #{fruitController.selectedFruits} which delivers the subset back to the panel.
So the concept here is: You fetch all the user data once into the object data source and once that is loaded filter inside that class, no renewed retrieval or lookup required.
Let us know hoe it goes

Categories