public class StrBuffer {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer(); //5
sb.append("hello"); //6
foo(sb); //7
System.out.println(sb); //8
}
private static void foo(StringBuffer sb) {
// TODO Auto-generated method stub
sb.append("wow"); //1
sb = new StringBuffer(); //2
sb.append("foo"); //3
System.out.println(sb); //4
}
}
in the above when i print in line8. output is "hellowow" .... can some one explain this please?
sb.append("wow"); //1
You just mutated the StringBuffer instance you passed in.
sb = new StringBuffer(); //2
You just assigned your local parameter to point to a new StringBuffer instance. This has no effect on the caller or on the old instance.
At first, you pass a reference to main's sb to foo.
In foo, you append "wow" to the referenced object.
Then, in foo, you create a new StringBuffer object, and change the local sb to point to it.
It might be clearer if I rename the reference:
public static void main(String[] args) {
StringBuffer sb = new StringBuffer(); //5
sb.append("hello"); //6
foo(sb); //7
System.out.println(sb); //8
}
private static void foo(StringBuffer ref) {
ref.append("wow"); //1
ref = new StringBuffer(); //2
ref.append("foo"); //3
System.out.println(ref); //4
}
'ref', as passed in to foo, is a just a reference to main's sb. You can operate on ref (ie., sb) in foo until you changed ref to refer to a different object.
Related
I have written a code in java that reads the ontology and print the triplets. the code is working fine. i want to hide the URI's in output and also print the output in the tree hierarchy form. Currently it gives me output in lines. Any idea how can i do this.
Tree Form Like:
Thing
Class
SubClass
Individual
so on ...
this is the ReadOntology class, this class i use in servlet.
public class ReadOntology {
public static OntModel model;
public static void run(String ontologyInFile) {
model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null);
InputStream ontologyIn = FileManager.get().open(ontologyInFile);
loadModel(model, ontologyIn);
}
protected static void loadModel(OntModel m, InputStream ontologyIn) {
try {
m.read(ontologyIn, "RDF/XML");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
this is the servlet
public class Ontology extends HttpServlet{
OntClass ontClass = null;
public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException
{
PrintWriter out = res.getWriter();
ServletContext context = this.getServletContext();
String fullPath = context.getRealPath("/WEB-INF/Data/taxi.owl");
ReadOntology.run(fullPath);
SimpleSelector selector = new SimpleSelector(null, null, (RDFNode)null);
StmtIterator iter = ReadOntology.model.listStatements(selector);
while(iter.hasNext()) {
Statement stmt = iter.nextStatement();
out.print(stmt.getSubject().toString());
out.print(stmt.getPredicate().toString());
out.println(stmt.getObject().toString());
}
}
}
As one step towards your goal, this groups the statements by subject, and for the predicates only shows the local name:
ResIterator resIt = ReadOntology.model.listSubjects()
while (resIt.hasNext()) {
Resource r = resIt.nextResource();
out.println(r);
StmtIterator iter = r.listProperties();
while (iter.hasNext()) {
Statement stmt = iter.nextStatement();
out.print(" ");
out.print(stmt.getPredicate().getLocalName());
out.println(stmt.getObject());
}
}
There are lots of useful methods in the API for Resource and Model.
To render a full class tree, use the methods on OntModel and OntClass. Perhaps:
private void printClass(Writer out, OntClass clazz, int indentation) {
String space = ' '.repeat(indentation);
// print space + clazz.getLocalName()
...
// iterate over clazz.listSubClasses(true)
// and call printClass for each with indentation increased by 1
...
// iterator over clazz.listInstances()
// and print all their properties as in the
// snippet above but with space added
}
Then in the service method, iterate over the OntModel's classes, and for any where hasSuperClass() is false, call printClass(out, clazz, 0).
I am learning zookeeper and trying out the Curator framework for service discoveries. However, I am facing a weird issue that I have difficulties to figure out. The problem is when I tried to register an instance via serviceDiscovery, the cacheChanged event of the serviceCache gets triggered three times. When I removed an instance, it is only triggered once, which is the expected behavior. Please see the code below:
public class DiscoveryExample {
private static String PATH = "/base";
static ServiceDiscovery<InstanceDetails> serviceDiscovery = null;
public static void main(String[] args) throws Exception {
CuratorFramework client = null;
try {
// this is the ip address of my VM
client = CuratorFrameworkFactory.newClient("192.168.149.129:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
JsonInstanceSerializer<InstanceDetails> serializer = new JsonInstanceSerializer<InstanceDetails>(
InstanceDetails.class);
serviceDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetails.class)
.client(client)
.basePath(PATH)
.serializer(serializer)
.build();
serviceDiscovery.start();
ServiceCache<InstanceDetails> serviceCache = serviceDiscovery.serviceCacheBuilder()
.name("product")
.build();
serviceCache.addListener(new ServiceCacheListener() {
#Override
public void stateChanged(CuratorFramework curator, ConnectionState state) {
// TODO Auto-generated method stub
System.out.println("State Changed to " + state.name());
}
// THIS IS THE PART GETS TRIGGERED MULTIPLE TIMES
#Override
public void cacheChanged() {
System.out.println("Cached Changed ");
List<ServiceInstance<InstanceDetails>> list = serviceCache.getInstances();
Iterator<ServiceInstance<InstanceDetails>> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next().getAddress());
}
}
});
serviceCache.start();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.print("> ");
String line = in.readLine();
} finally {
CloseableUtils.closeQuietly(serviceDiscovery);
CloseableUtils.closeQuietly(client);
}
}
}
AND
public class RegisterApplicationServer {
final static String PATH = "/base";
static ServiceDiscovery<InstanceDetails> serviceDiscovery = null;
public static void main(String[] args) throws Exception {
CuratorFramework client = null;
try {
client = CuratorFrameworkFactory.newClient("192.168.149.129:2181", new ExponentialBackoffRetry(1000, 3));
client.start();
JsonInstanceSerializer<InstanceDetails> serializer = new JsonInstanceSerializer<InstanceDetails>(
InstanceDetails.class);
serviceDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetails.class).client(client).basePath(PATH)
.serializer(serializer).build();
serviceDiscovery.start();
// SOME OTHER CODE THAT TAKES CARES OF USER INPUT...
} finally {
CloseableUtils.closeQuietly(serviceDiscovery);
CloseableUtils.closeQuietly(client);
}
}
private static void addInstance(String[] args, CuratorFramework client, String command,
ServiceDiscovery<InstanceDetails> serviceDiscovery) throws Exception {
// simulate a new instance coming up
// in a real application, this would be a separate process
if (args.length < 2) {
System.err.println("syntax error (expected add <name> <description>): " + command);
return;
}
StringBuilder description = new StringBuilder();
for (int i = 1; i < args.length; ++i) {
if (i > 1) {
description.append(' ');
}
description.append(args[i]);
}
String serviceName = args[0];
ApplicationServer server = new ApplicationServer(client, PATH, serviceName, description.toString());
server.start();
serviceDiscovery.registerService(server.getThisInstance());
System.out.println(serviceName + " added");
}
private static void deleteInstance(String[] args, String command, ServiceDiscovery<InstanceDetails> serviceDiscovery) throws Exception {
// in a real application, this would occur due to normal operation, a
// crash, maintenance, etc.
if (args.length != 2) {
System.err.println("syntax error (expected delete <name>): " + command);
return;
}
final String serviceName = args[0];
Collection<ServiceInstance<InstanceDetails>> set = serviceDiscovery.queryForInstances(serviceName);
Iterator<ServiceInstance<InstanceDetails>> it = set.iterator();
while (it.hasNext()) {
ServiceInstance<InstanceDetails> si = it.next();
if (si.getPayload().getDescription().indexOf(args[1]) != -1) {
serviceDiscovery.unregisterService(si);
}
}
System.out.println("Removed an instance of: " + serviceName);
}
}
I appriciate if anyone can please point out where I am doing wrong and maybe can share some good materials/examples so I can refer to. The official website and the examples on github does not help a lot.
I need to analyze path data of PDF files and manipulate content with iText 7. Manipulations include deletion/replacemant and coloring.
I can analyze the graphics alright with something like the following code:
public class ContentParsing {
public static void main(String[] args) throws IOException {
new ContentParsing().inspectPdf("testdata/test.pdf");
}
public void inspectPdf(String path) throws IOException {
File file = new File(path);
PdfDocument pdf = new PdfDocument(new PdfReader(file.getAbsolutePath()));
PdfDocumentContentParser parser = new PdfDocumentContentParser(pdf);
for (int i=1; i<=pdf.getNumberOfPages(); i++) {
parser.processContent(i, new PathEventListener());
}
pdf.close();
}
}
public class PathEventListener implements IEventListener {
public void eventOccurred(IEventData eventData, EventType eventType) {
PathRenderInfo pathRenderInfo = (PathRenderInfo) eventData;
for ( Subpath subpath : pathRenderInfo.getPath().getSubpaths() ) {
for ( IShape segment : subpath.getSegments() ) {
// Here goes some path analysis code
System.out.println(segment.getBasePoints());
}
}
}
public Set<EventType> getSupportedEvents() {
Set<EventType> supportedEvents = new HashSet<EventType>();
supportedEvents.add(EventType.RENDER_PATH);
return supportedEvents;
}
}
Now, what's the way to go with manipulating things and writing them back to the PDF? Do I have to construct an entirely new PDF document and copy everything over (in manipulated form), or can I somehow manipulate the read PDF data directly?
Now, what's the way to go with manipulating things and writing them back to the PDF? Do I have to construct an entirely new PDF document and copy everything over (in manipulated form), or can I somehow manipulate the read PDF data directly?
In essence you are looking for a class which is not merely parsing a PDF content stream and signaling the instructions in it like the PdfCanvasProcessor (the PdfDocumentContentParser you use is merely a very thin wrapper for PdfCanvasProcessor) but which also creates the content stream anew with the instructions you forward back to it.
A generic content stream editor class
For iText 5.5.x a proof-of-concept for such a content stream editor class can be found in this answer (the Java version is a bit further down in the answer text).
This is a port of that proof-of-concept to iText 7:
public class PdfCanvasEditor extends PdfCanvasProcessor
{
/**
* This method edits the immediate contents of a page, i.e. its content stream.
* It explicitly does not descent into form xobjects, patterns, or annotations.
*/
public void editPage(PdfDocument pdfDocument, int pageNumber) throws IOException
{
if ((pdfDocument.getReader() == null) || (pdfDocument.getWriter() == null))
{
throw new PdfException("PdfDocument must be opened in stamping mode.");
}
PdfPage page = pdfDocument.getPage(pageNumber);
PdfResources pdfResources = page.getResources();
PdfCanvas pdfCanvas = new PdfCanvas(new PdfStream(), pdfResources, pdfDocument);
editContent(page.getContentBytes(), pdfResources, pdfCanvas);
page.put(PdfName.Contents, pdfCanvas.getContentStream());
}
/**
* This method processes the content bytes and outputs to the given canvas.
* It explicitly does not descent into form xobjects, patterns, or annotations.
*/
public void editContent(byte[] contentBytes, PdfResources resources, PdfCanvas canvas)
{
this.canvas = canvas;
processContent(contentBytes, resources);
this.canvas = null;
}
/**
* <p>
* This method writes content stream operations to the target canvas. The default
* implementation writes them as they come, so it essentially generates identical
* copies of the original instructions the {#link ContentOperatorWrapper} instances
* forward to it.
* </p>
* <p>
* Override this method to achieve some fancy editing effect.
* </p>
*/
protected void write(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands)
{
PdfOutputStream pdfOutputStream = canvas.getContentStream().getOutputStream();
int index = 0;
for (PdfObject object : operands)
{
pdfOutputStream.write(object);
if (operands.size() > ++index)
pdfOutputStream.writeSpace();
else
pdfOutputStream.writeNewLine();
}
}
//
// constructor giving the parent a dummy listener to talk to
//
public PdfCanvasEditor()
{
super(new DummyEventListener());
}
//
// Overrides of PdfContentStreamProcessor methods
//
#Override
public IContentOperator registerContentOperator(String operatorString, IContentOperator operator)
{
ContentOperatorWrapper wrapper = new ContentOperatorWrapper();
wrapper.setOriginalOperator(operator);
IContentOperator formerOperator = super.registerContentOperator(operatorString, wrapper);
return formerOperator instanceof ContentOperatorWrapper ? ((ContentOperatorWrapper)formerOperator).getOriginalOperator() : formerOperator;
}
//
// members holding the output canvas and the resources
//
protected PdfCanvas canvas = null;
//
// A content operator class to wrap all content operators to forward the invocation to the editor
//
class ContentOperatorWrapper implements IContentOperator
{
public IContentOperator getOriginalOperator()
{
return originalOperator;
}
public void setOriginalOperator(IContentOperator originalOperator)
{
this.originalOperator = originalOperator;
}
#Override
public void invoke(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands)
{
if (originalOperator != null && !"Do".equals(operator.toString()))
{
originalOperator.invoke(processor, operator, operands);
}
write(processor, operator, operands);
}
private IContentOperator originalOperator = null;
}
//
// A dummy event listener to give to the underlying canvas processor to feed events to
//
static class DummyEventListener implements IEventListener
{
#Override
public void eventOccurred(IEventData data, EventType type)
{ }
#Override
public Set<EventType> getSupportedEvents()
{
return null;
}
}
}
(PdfCanvasEditor.java)
The explanations from the iText 5 answer still apply, the parsing framework has not changed much from iText 5.5.x to iText 7.0.x.
Usage examples
Unfortunately you wrote in very vague terms about how exactly you want to change the contents. Thus I simply ported some iText 5 samples which made use of the original iText 5 content stream editor class:
Watermark removal
These are ports of the use cases in this answer.
testRemoveBoldMTTextDocument
This example drops all text written in a font the name of which ends with "BoldMT":
try ( InputStream resource = getClass().getResourceAsStream("document.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "document-noBoldMTText.pdf"));
PdfWriter pdfWriter = new PdfWriter(result);
PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter) )
{
PdfCanvasEditor editor = new PdfCanvasEditor()
{
#Override
protected void write(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands)
{
String operatorString = operator.toString();
if (TEXT_SHOWING_OPERATORS.contains(operatorString))
{
if (getGraphicsState().getFont().getFontProgram().getFontNames().getFontName().endsWith("BoldMT"))
return;
}
super.write(processor, operator, operands);
}
final List<String> TEXT_SHOWING_OPERATORS = Arrays.asList("Tj", "'", "\"", "TJ");
};
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++)
{
editor.editPage(pdfDocument, i);
}
}
(EditPageContent.java test method testRemoveBoldMTTextDocument)
testRemoveBigTextDocument
This example drops all text written with a large font size:
try ( InputStream resource = getClass().getResourceAsStream("document.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "document-noBigText.pdf"));
PdfWriter pdfWriter = new PdfWriter(result);
PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter) )
{
PdfCanvasEditor editor = new PdfCanvasEditor()
{
#Override
protected void write(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands)
{
String operatorString = operator.toString();
if (TEXT_SHOWING_OPERATORS.contains(operatorString))
{
if (getGraphicsState().getFontSize() > 100)
return;
}
super.write(processor, operator, operands);
}
final List<String> TEXT_SHOWING_OPERATORS = Arrays.asList("Tj", "'", "\"", "TJ");
};
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++)
{
editor.editPage(pdfDocument, i);
}
}
(EditPageContent.java test method testRemoveBigTextDocument)
Text color change
This is a port of the use case in this answer.
testChangeBlackTextToGreenDocument
This example changes the color of black text to green.
try ( InputStream resource = getClass().getResourceAsStream("document.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "document-blackTextToGreen.pdf"));
PdfWriter pdfWriter = new PdfWriter(result);
PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter) )
{
PdfCanvasEditor editor = new PdfCanvasEditor()
{
#Override
protected void write(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands)
{
String operatorString = operator.toString();
if (TEXT_SHOWING_OPERATORS.contains(operatorString))
{
if (currentlyReplacedBlack == null)
{
Color currentFillColor = getGraphicsState().getFillColor();
if (Color.BLACK.equals(currentFillColor))
{
currentlyReplacedBlack = currentFillColor;
super.write(processor, new PdfLiteral("rg"), Arrays.asList(new PdfNumber(0), new PdfNumber(1), new PdfNumber(0), new PdfLiteral("rg")));
}
}
}
else if (currentlyReplacedBlack != null)
{
if (currentlyReplacedBlack instanceof DeviceCmyk)
{
super.write(processor, new PdfLiteral("k"), Arrays.asList(new PdfNumber(0), new PdfNumber(0), new PdfNumber(0), new PdfNumber(1), new PdfLiteral("k")));
}
else if (currentlyReplacedBlack instanceof DeviceGray)
{
super.write(processor, new PdfLiteral("g"), Arrays.asList(new PdfNumber(0), new PdfLiteral("g")));
}
else
{
super.write(processor, new PdfLiteral("rg"), Arrays.asList(new PdfNumber(0), new PdfNumber(0), new PdfNumber(0), new PdfLiteral("rg")));
}
currentlyReplacedBlack = null;
}
super.write(processor, operator, operands);
}
Color currentlyReplacedBlack = null;
final List<String> TEXT_SHOWING_OPERATORS = Arrays.asList("Tj", "'", "\"", "TJ");
};
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++)
{
editor.editPage(pdfDocument, i);
}
}
(EditPageContent.java test method testChangeBlackTextToGreenDocument)
I searched some examples on the Internet and many of them use the OGraphDatabase. However, when these code file was compiled, a exception that says cant find the symbol of "OGraphDatabase" was throwed.
Blow is the source code:
public class TestTreeGraph {
static OGraphDatabase db;
//static int i=0;
//static ODocument currentNode;
public static void main(String[] args) throws FileNotFoundException{
String dbpath="/Users/wuguirongsg/orientdb/orientdbgraph";
File dbfile = new File(dbpath);
if(!dbfile.exists()){
//dbfile.mkdirs();
db = new OGraphDatabase("local:"+dbpath).create();
db = new OGraphDatabase("local:"+dbpath).open("admin", "admin");
}else{
db = new OGraphDatabase("local:"+dbpath).open("admin", "admin");
}
ODocument rootNode = db.createVertex().field("id", 0);
int i=1;
createNode(rootNode,i);
db.setRoot("treegraph", rootNode);
}
private static void createNode(ODocument node,int i){
if(i>=20){
System.out.println("i>=10================== back ");
return ;
}
ODocument leftNode = db.createVertex().field("id", i + "_vertex_left");
System.out.println("create "+i + "_vertex_left ");
ODocument rightNode = db.createVertex().field("id", i + "_vertex_right");
System.out.println("create "+i + "_vertex_right ");
ODocument edgeleft = db.createEdge( node, leftNode);
ODocument edgeright = db.createEdge( node, rightNode);
edgeleft.save();
edgeright.save();
//currentNode = leftNode;
System.out.println("go left");
createNode(leftNode,i+1);
System.out.println("go right");
createNode(rightNode,i+1);
System.out.println("==================");
}
}
OGraphDatabase has been deprecated ages ago. You can use OrientGraph.
Example
String dbpath="C:/test";
OrientGraphFactory factory = new OrientGraphFactory("plocal:"+dbpath);
// if the database doesn't exist it is created and opened
// if the database exists, it is opened
OrientGraph db = factory.getTx();
// inserting a vertex
Vertex rootNode=db.addVertex("class:V");
rootNode.setProperty("myId","0");
db.shutdown();
I'm trying to send serialize class object on the server side. First I serialize object in byte array, then I take array length and send lenght as integer and send array on the srever side. But programm fold with NullPointerException in stacktrace. All class-fields is static. What a problem?
public class Main {
public static int port = 8085;
public static String address = "127.0.0.1";
public static Socket clientSocket;
public static InputStream in;
public static OutputStream out;
public static DataInputStream din;
public static DataOutputStream dout;
public static boolean stop = false;
public static int l;
public Main(){
try {
InetAddress ipAddress = InetAddress.getByName(address);
clientSocket = new Socket(ipAddress, port);
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
din = new DataInputStream(in);
dout = new DataOutputStream(out);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
int number = 5;
String str = "Hello world!";
byte[] bt = str.getBytes();
ArrayList<Byte> array = new ArrayList<Byte>();
for(int i=0; i<bt.length; i++){
array.add(bt[i]);
}
while(!stop){
Template protocol = new Template(number, str, array);
byte[] serializeObject = SerializationUtils.serialize(protocol);
l = serializeObject.length;
try {
dout.writeInt(l); //NPE
dout.write(serializeObject); //NPE
dout.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
You're invoking the static field dout without it being initialized. By default, Java object references are initialized to null. The code that initializes those fields is in the constructor, which is not being called since you're inside the static main() method, which is not tied to an instance. So your reference is still null, hence the NullPointerException when you invoke your dout.writeInt(l);.
Unless you explicitly create a Main() instance, as in Main myMain = new Main();, your main method needs to initialize your dout reference, since it's null.
Since this seems more like a simple communication test, just move the initialization code in the constructor to your main method.