Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to build a plug-in that gets loaded when the Notes client (8.5.2++) loads that gets called whenever a document is opened and get the (Notes) URL of that document. What extension points and APIs do I need?
Clarification:
I do know how to get to the current document (NotesUIWorkspace.currentDocument). What I don't know is how (and when) to register a listener to get notified.
Special challenge: documents can be opened in Framesets (more than one) and documents can be opened as part of a composite page. The Frameset isn't a big concern, but the composite. If this would require to listen to any page opening and inspect it - I'm fine with that
We have solved this by getting all request of anykind of "post selection". The following Code snipped is from a sidebarplugin and is called in createViewPart():
m_Observer = new NotesSelectionObserverImpl();
NotesSelectionObservable cObservable = new NotesSelectionObservable();
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().addPostSelectionListener(cObservable);
cObservable.addObserver(this.m_Observer);
The first part of the magic is "PlattformUI ..... .addPostSelecitonListener();" On this point we register our listener, witch is als based on a observer pattern.
class NotesSelectionObserverImpl implements NotesSelectionObserver {
#Override
public void onSelectionChange(NotesSelectionContext cContext)
throws NotesException {
Database ndbCurrent = cContext.getDatabase();
Document docCurrent = cContext.getDocument();
if (ndbCurrent != null && docCurrent != null) {
String strEMail = "";
if (docCurrent.getItemValueString("Form").equals("Memo")
|| docCurrent.getItemValueString("Form")
.equals("Reply")) {
strEMail = docCurrent.getItemValueString("From");
strEMail = parseEMail(strEMail);
System.out.println("EMAIL: " + strEMail);
ContextCommand ccCurrent = new ContextCommand(strEMail,
docCurrent.getItemValueString("Subject"));
m_State.doFeedAction(false, m_Feeds.get(Activator.FEED_CONTEXT_ID), ccCurrent);
}
}
}
#Override
public void onUpdateAfterSelectionChange() {
// TODO Auto-generated method stub
}
}
The NotesSelectionObserver is a interface with the following definition:
import lotus.domino.NotesException;
public interface NotesSelectionObserver
{
void onSelectionChange(NotesSelectionContext cContext) throws NotesException;
void onUpdateAfterSelectionChange();
}
The NotesSelecitonContext is a other Interface that delivers all the information about the Selection. Here the definition:
import lotus.domino.Database;
import lotus.domino.Document;
public interface NotesSelectionContext
{
public Database getDatabase();
public Document getDocument();
public String getField();
}
So and now the last part, witch is the clue.... the NotesSelectionObservable:
import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;
import java.util.Vector;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.NotesException;
import lotus.domino.Session;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.INullSelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.progress.UIJob;
import com.ibm.csi.types.DocumentSummary;
import com.ibm.notes.java.api.util.NotesSessionJob;
import com.ibm.notes.java.ui.documents.NotesUIField;
import com.ibm.workplace.noteswc.selection.NotesApplicationInfo;
import com.ibm.workplace.noteswc.selection.NotesFieldSelection;
import com.ibm.workplace.noteswc.selection.NotesTextSelection;
public class NotesSelectionObservable implements INullSelectionListener {
public void addObserver(NotesSelectionObserver cObserver) {
if (!this.m_cObserverList.contains(cObserver))
this.m_cObserverList.add(cObserver);
}
public void removeObserver(NotesSelectionObserver cObserver) {
this.m_cObserverList.remove(cObserver);
}
public void selectionChanged(IWorkbenchPart cPart, ISelection cSelection) {
if (cSelection == null || cSelection.isEmpty())
this.clearSelection();
else if (cSelection instanceof StructuredSelection) {
Object cObj = ((StructuredSelection) cSelection).getFirstElement();
if (cObj instanceof DocumentSummary) {
DocumentSummary cSummary = (DocumentSummary) cObj;
this.setURL(cSummary.getUrl());
if (cSummary.getDocumentKey() != null)
this.setURL(cSummary.getDocumentKey().getUniqueId());
} else if (cObj instanceof NotesApplicationInfo) {
NotesApplicationInfo cInfo = (NotesApplicationInfo) cObj;
this.setURL(cInfo.getUrl());
}
if (cObj instanceof NotesFieldSelection) {
NotesUIField f = ((NotesFieldSelection)cObj).getCurrentField();
this.setField(f.getName());
}
if (cObj instanceof NotesTextSelection) {
// String strOut = ((NotesTextSelection) cObj).getText();
// System.out.println("Selektierter Text: " + strOut);
}
if (false) {
Class<? extends Object> c;
String cl = null;
for (c = cObj.getClass(); c != null; c = c.getSuperclass()) {
if (c.equals(Object.class))
break;
cl = cl != null ? cl + " : " + c.getName() : c.getName();
}
System.out.println("Type of selected object: " + cl);
}
}
if (this.m_bModified) {
this.startJob();
this.m_bModified = false;
}
}
private void clearSelection() {
this.m_strDatabaseRepID = null;
this.m_strDatabaseServer = null;
this.m_strDocumentUNID = null;
this.m_strDesginElement = null;
this.m_strField = null;
this.m_bModified = true;
}
private void setDatabase(String strRepID, String strServer) {
if (strRepID.equals(this.m_strDatabaseRepID) == false
|| (strServer != null && this.m_strDatabaseServer == null)
|| (this.m_strDatabaseServer != null && this.m_strDatabaseServer.equals(strServer) == false)) {
this.m_strDatabaseRepID = strRepID;
this.m_strDatabaseServer = strServer;
this.m_strDesginElement = null;
this.m_strDocumentUNID = null;
this.m_strField = null;
this.m_bModified = true;
}
}
private void setDesignElement(String strUNID) {
if (!strUNID.equals(this.m_strDesginElement)) {
this.m_strDesginElement = strUNID;
this.m_strDocumentUNID = null;
this.m_strField = null;
this.m_bModified = true;
}
}
private void setDocument(String strDocumentUNID) {
if (!strDocumentUNID.equals(this.m_strDocumentUNID)) {
this.m_strDocumentUNID = strDocumentUNID;
this.m_strField = null;
this.m_bModified = true;
}
}
private void setField(String strField) {
if (!strField.equals(this.m_strField)) {
this.m_strField = strField;
this.m_bModified = true;
}
}
private void setURL(String strURL) {
if (strURL == null || strURL.isEmpty())
return;
URL cURL;
try {
cURL = new URL(strURL);
} catch (MalformedURLException e) {
return;
}
if (!cURL.getProtocol().equalsIgnoreCase("notes"))
return;
StringTokenizer cToken = new StringTokenizer(cURL.getPath()
.substring(1), "/");
if (cToken.hasMoreElements())
this.setDatabase(cToken.nextToken(),
cURL.getHost().isEmpty() ? null : cURL.getHost());
else
return;
if (cToken.hasMoreElements())
this.setDesignElement(cToken.nextToken());
else
return;
if (cToken.hasMoreElements())
this.setDocument(cToken.nextToken());
}
private void startJob() {
if (this.m_strDatabaseRepID != null && this.m_cObserverList.size() > 0) {
Job cJob = new TheJob(this);
cJob.schedule();
try {
cJob.join();
for (NotesSelectionObserver o : this.m_cObserverList)
o.onUpdateAfterSelectionChange();
this.m_bModified = false;
} catch (InterruptedException e) {
return;
}
cJob = new TheUIJob(this);
cJob.schedule();
}
}
private class NotesSelectionContextImp implements NotesSelectionContext {
public Database getDatabase() {
return cDatabase;
}
public Document getDocument() {
return cDocument;
}
public String getField() {
return strField;
}
public Database cDatabase;
public Document cDocument;
public String strField;
}
private class TheJob extends NotesSessionJob {
public TheJob(NotesSelectionObservable cObservable) {
super(cObservable.getClass().getName() + ".selectionChanged()");
this.m_strRepID = cObservable.m_strDatabaseRepID;
this.m_strServer = cObservable.m_strDatabaseServer != null ? cObservable.m_strDatabaseServer
: "";
if (this.m_strServer.contains("%2F"))
this.m_strServer = this.m_strServer.replace("%2F", "/");
this.m_strDocumentUNID = cObservable.m_strDocumentUNID;
this.m_cContext.strField = cObservable.m_strField;
this.m_cObservable = cObservable;
}
protected IStatus runInNotesThread(Session cSession,
IProgressMonitor cProgress) throws NotesException {
this.m_cContext.cDatabase = cSession.getDbDirectory(this.m_strServer).openDatabaseByReplicaID(this.m_strRepID);
if (!this.m_cContext.cDatabase.isOpen()) {
this.m_cContext.cDatabase.open();
}
this.m_cContext.cDocument = this.m_strDocumentUNID != null ? this.m_cContext.cDatabase.getDocumentByUNID(this.m_strDocumentUNID)
: null;
for (NotesSelectionObserver o : this.m_cObservable.m_cObserverList)
o.onSelectionChange(this.m_cContext);
return Status.OK_STATUS;
}
private NotesSelectionContextImp m_cContext = new NotesSelectionContextImp();
private NotesSelectionObservable m_cObservable;
private String m_strRepID;
private String m_strServer;
private String m_strDocumentUNID;
}
private class TheUIJob extends UIJob {
public TheUIJob(NotesSelectionObservable cObservable) {
super(cObservable.getClass().getName() + ".selectionChanged()");
this.m_cObservable = cObservable;
}
public IStatus runInUIThread(IProgressMonitor arg0) {
for (NotesSelectionObserver o : this.m_cObservable.m_cObserverList)
o.onUpdateAfterSelectionChange();
this.m_cObservable.m_bModified = false;
return Status.OK_STATUS;
}
private NotesSelectionObservable m_cObservable;
}
private String m_strDatabaseRepID = null;
private String m_strDatabaseServer = null;
private String m_strDesginElement = null;
private String m_strDocumentUNID = null;
private String m_strField = null;
private boolean m_bModified = false;
private Vector<NotesSelectionObserver> m_cObserverList = new Vector<NotesSelectionObserver>();
}
You have also asked about the list of plugins:
org.eclipse.ui,
org.eclipse.core.runtime,
com.ibm.notes.java.api;bundle-version="1.5.1",
com.ibm.notes.java.ui;bundle-version="8.5.1",
com.ibm.csi;bundle-version="1.5.1",
com.ibm.notes.client;bundle-version="8.5.1"
We will bring this code also as a plugin to the openNTF Community. I think anybody who wants to extend the notesclient via Sidebars need to be aware on witch context a user is and wants to response to this context.
Related
I am trying to learn how to use Apache Zookeeper. A part of this is I need to check if the parent node has been created and if it hasn't, then I need to create the node, then populate the registry with information on the services currently running in the cluster. This is happening in the method initialise(). I cannot figure out the checking if the parent node exists. The code I have is what I have so far.
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ServiceRegistry implements Watcher {
private String zookeeperAddress = "localhost:2181";
private int sessionTimeout = 3000;
private ZooKeeper zooKeeper;
private String currentZNodeName;
private String serviceName = "";
private String serviceAddress = "";
private static final String SERVICES_NAMESPACE = "/services";
public ServiceRegistry(String zookeeperAddress, int sessionTimeout) {
this.sessionTimeout = sessionTimeout;
this.zookeeperAddress = zookeeperAddress;
}
//Works
public void connectToZookeeper() throws IOException {
this.zooKeeper = new ZooKeeper(zookeeperAddress, sessionTimeout, this);
}
public void process(WatchedEvent event) {
switch (event.getType()){
case None:
if(event.getState() == Watcher.Event.KeeperState.SyncConnected){
System.out.println("Successfully connected to Zookeeper");
}else{
synchronized (zooKeeper){
System.out.println("Disconnected from Zookeeper");
zooKeeper.notifyAll();
}
}
break;
case NodeCreated:
System.out.println("Node created");
try {
initialise();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (KeeperException e) {
throw new RuntimeException(e);
}
break;
case NodeDataChanged:
System.out.println("Node data changed");
getServices();
break;
}
}
public void initialise() throws InterruptedException, KeeperException {
Stat servicesStat = null;
if(servicesStat == null){
String znodePrefix = SERVICES_NAMESPACE + "/c_";
String znodeFullPath = zooKeeper.create(znodePrefix, new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("znode name " + znodeFullPath);
servicesStat = zooKeeper.exists(SERVICES_NAMESPACE + "/", this);
}
}
public void run() throws InterruptedException {
synchronized (zooKeeper){
zooKeeper.wait();
}
}
I am using WebSocketClient class to get the data from websocket in my android app but when anything change in Internet connection ( Disconnect from Internet ) it gives the following error in WebSocketClient.java file
USER_COMMENT=null
ANDROID_VERSION=10
APP_VERSION_NAME=0.0.1
BRAND=google
PHONE_MODEL=Android SDK built for x86_64
CUSTOM_DATA=
STACK_TRACE=java.lang.AssertionError
at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:190)
at java.lang.Thread.run(Thread.java:919)
But the WebSocketClient.java is read only file it is coming from java-websocket-1.3.0.jar file
WebSocketClient.java
package org.java_websocket.client;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.CountDownLatch;
import org.java_websocket.SocketChannelIOHelper;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketAdapter;
import org.java_websocket.WebSocketFactory;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.WrappedByteChannel;
import org.java_websocket.WebSocket.READYSTATE;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_10;
import org.java_websocket.exceptions.InvalidHandshakeException;
import org.java_websocket.handshake.HandshakeImpl1Client;
import org.java_websocket.handshake.Handshakedata;
import org.java_websocket.handshake.ServerHandshake;
public abstract class WebSocketClient extends WebSocketAdapter implements Runnable {
protected URI uri;
private WebSocketImpl conn;
private SocketChannel channel;
private ByteChannel wrappedchannel;
private Thread writethread;
private Thread readthread;
private Draft draft;
private Map<String, String> headers;
private CountDownLatch connectLatch;
private CountDownLatch closeLatch;
private int timeout;
private WebSocketClient.WebSocketClientFactory wsfactory;
private InetSocketAddress proxyAddress;
public WebSocketClient(URI serverURI) {
this(serverURI, new Draft_10());
}
public WebSocketClient(URI serverUri, Draft draft) {
this(serverUri, draft, (Map)null, 0);
}
public WebSocketClient(URI serverUri, Draft draft, Map<String, String> headers, int connecttimeout) {
this.uri = null;
this.conn = null;
this.channel = null;
this.wrappedchannel = null;
this.connectLatch = new CountDownLatch(1);
this.closeLatch = new CountDownLatch(1);
this.timeout = 0;
this.wsfactory = new DefaultWebSocketClientFactory(this);
this.proxyAddress = null;
if (serverUri == null) {
throw new IllegalArgumentException();
} else if (draft == null) {
throw new IllegalArgumentException("null as draft is permitted for `WebSocketServer` only!");
} else {
this.uri = serverUri;
this.draft = draft;
this.headers = headers;
this.timeout = connecttimeout;
try {
this.channel = SelectorProvider.provider().openSocketChannel();
this.channel.configureBlocking(true);
} catch (IOException var6) {
this.channel = null;
this.onWebsocketError((WebSocket)null, var6);
}
if (this.channel == null) {
this.conn = (WebSocketImpl)this.wsfactory.createWebSocket(this, draft, (Socket)null);
this.conn.close(-1, "Failed to create or configure SocketChannel.");
} else {
this.conn = (WebSocketImpl)this.wsfactory.createWebSocket(this, draft, this.channel.socket());
}
}
}
public URI getURI() {
return this.uri;
}
public Draft getDraft() {
return this.draft;
}
public void connect() {
if (this.writethread != null) {
throw new IllegalStateException("WebSocketClient objects are not reuseable");
} else {
this.writethread = new Thread(this);
this.writethread.start();
}
}
public boolean connectBlocking() throws InterruptedException {
this.connect();
this.connectLatch.await();
return this.conn.isOpen();
}
public void close() {
if (this.writethread != null) {
this.conn.close(1000);
}
}
public void closeBlocking() throws InterruptedException {
this.close();
this.closeLatch.await();
}
public void send(String text) throws NotYetConnectedException {
this.conn.send(text);
}
public void send(byte[] data) throws NotYetConnectedException {
this.conn.send(data);
}
public void run() {
if (this.writethread == null) {
this.writethread = Thread.currentThread();
}
this.interruptableRun();
assert !this.channel.isOpen();
}
private final void interruptableRun() {
if (this.channel != null) {
try {
String host;
int port;
if (this.proxyAddress != null) {
host = this.proxyAddress.getHostName();
port = this.proxyAddress.getPort();
} else {
host = this.uri.getHost();
port = this.getPort();
}
this.channel.connect(new InetSocketAddress(host, port));
this.conn.channel = this.wrappedchannel = this.createProxyChannel(this.wsfactory.wrapChannel(this.channel, (SelectionKey)null, host, port));
this.timeout = 0;
this.sendHandshake();
this.readthread = new Thread(new WebSocketClient.WebsocketWriteThread());
this.readthread.start();
} catch (ClosedByInterruptException var3) {
this.onWebsocketError((WebSocket)null, var3);
return;
} catch (Exception var4) {
this.onWebsocketError(this.conn, var4);
this.conn.closeConnection(-1, var4.getMessage());
return;
}
ByteBuffer buff = ByteBuffer.allocate(WebSocketImpl.RCVBUF);
try {
while(this.channel.isOpen()) {
if (SocketChannelIOHelper.read(buff, this.conn, this.wrappedchannel)) {
this.conn.decode(buff);
} else {
this.conn.eot();
}
if (this.wrappedchannel instanceof WrappedByteChannel) {
WrappedByteChannel w = (WrappedByteChannel)this.wrappedchannel;
if (w.isNeedRead()) {
while(SocketChannelIOHelper.readMore(buff, this.conn, w)) {
this.conn.decode(buff);
}
this.conn.decode(buff);
}
}
}
} catch (CancelledKeyException var5) {
this.conn.eot();
} catch (IOException var6) {
this.conn.eot();
} catch (RuntimeException var7) {
this.onError(var7);
this.conn.closeConnection(1006, var7.getMessage());
}
}
}
private int getPort() {
int port = this.uri.getPort();
if (port == -1) {
String scheme = this.uri.getScheme();
if (scheme.equals("wss")) {
return 443;
} else if (scheme.equals("ws")) {
return 80;
} else {
throw new RuntimeException("unkonow scheme" + scheme);
}
} else {
return port;
}
}
private void sendHandshake() throws InvalidHandshakeException {
String part1 = this.uri.getPath();
String part2 = this.uri.getQuery();
String path;
if (part1 != null && part1.length() != 0) {
path = part1;
} else {
path = "/";
}
if (part2 != null) {
path = path + "?" + part2;
}
int port = this.getPort();
String host = this.uri.getHost() + (port != 80 ? ":" + port : "");
HandshakeImpl1Client handshake = new HandshakeImpl1Client();
handshake.setResourceDescriptor(path);
handshake.put("Host", host);
if (this.headers != null) {
Iterator i$ = this.headers.entrySet().iterator();
while(i$.hasNext()) {
Entry<String, String> kv = (Entry)i$.next();
handshake.put((String)kv.getKey(), (String)kv.getValue());
}
}
this.conn.startHandshake(handshake);
}
public READYSTATE getReadyState() {
return this.conn.getReadyState();
}
public final void onWebsocketMessage(WebSocket conn, String message) {
this.onMessage(message);
}
public final void onWebsocketMessage(WebSocket conn, ByteBuffer blob) {
this.onMessage(blob);
}
public final void onWebsocketOpen(WebSocket conn, Handshakedata handshake) {
this.connectLatch.countDown();
this.onOpen((ServerHandshake)handshake);
}
public final void onWebsocketClose(WebSocket conn, int code, String reason, boolean remote) {
this.connectLatch.countDown();
this.closeLatch.countDown();
if (this.readthread != null) {
this.readthread.interrupt();
}
this.onClose(code, reason, remote);
}
public final void onWebsocketError(WebSocket conn, Exception ex) {
this.onError(ex);
}
public final void onWriteDemand(WebSocket conn) {
}
public void onWebsocketCloseInitiated(WebSocket conn, int code, String reason) {
this.onCloseInitiated(code, reason);
}
public void onWebsocketClosing(WebSocket conn, int code, String reason, boolean remote) {
this.onClosing(code, reason, remote);
}
public void onCloseInitiated(int code, String reason) {
}
public void onClosing(int code, String reason, boolean remote) {
}
public WebSocket getConnection() {
return this.conn;
}
public final void setWebSocketFactory(WebSocketClient.WebSocketClientFactory wsf) {
this.wsfactory = wsf;
}
public final WebSocketFactory getWebSocketFactory() {
return this.wsfactory;
}
public InetSocketAddress getLocalSocketAddress(WebSocket conn) {
return this.channel != null ? (InetSocketAddress)this.channel.socket().getLocalSocketAddress() : null;
}
public InetSocketAddress getRemoteSocketAddress(WebSocket conn) {
return this.channel != null ? (InetSocketAddress)this.channel.socket().getLocalSocketAddress() : null;
}
public abstract void onOpen(ServerHandshake var1);
public abstract void onMessage(String var1);
public abstract void onClose(int var1, String var2, boolean var3);
public abstract void onError(Exception var1);
public void onMessage(ByteBuffer bytes) {
}
public ByteChannel createProxyChannel(ByteChannel towrap) {
return (ByteChannel)(this.proxyAddress != null ? new WebSocketClient.DefaultClientProxyChannel(towrap) : towrap);
}
public void setProxy(InetSocketAddress proxyaddress) {
this.proxyAddress = proxyaddress;
}
private class WebsocketWriteThread implements Runnable {
private WebsocketWriteThread() {
}
public void run() {
Thread.currentThread().setName("WebsocketWriteThread");
try {
while(!Thread.interrupted()) {
SocketChannelIOHelper.writeBlocking(WebSocketClient.this.conn, WebSocketClient.this.wrappedchannel);
}
} catch (IOException var2) {
WebSocketClient.this.conn.eot();
} catch (InterruptedException var3) {
}
}
}
public interface WebSocketClientFactory extends WebSocketFactory {
ByteChannel wrapChannel(SocketChannel var1, SelectionKey var2, String var3, int var4) throws IOException;
}
public class DefaultClientProxyChannel extends AbstractClientProxyChannel {
public DefaultClientProxyChannel(ByteChannel towrap) {
super(towrap);
}
public String buildHandShake() {
StringBuilder b = new StringBuilder();
String host = WebSocketClient.this.uri.getHost();
b.append("CONNECT ");
b.append(host);
b.append(":");
b.append(WebSocketClient.this.getPort());
b.append(" HTTP/1.1\n");
b.append("Host: ");
b.append(host);
b.append("\n");
return b.toString();
}
}
}
The third-party library has a description. You can write a class to inherit the WebSocketClient class and rewrite the code after network disconnection and reconnection. The code example of the third-party library is provided for reference.
I am using the following code to create a custom log as per my requirements.
But unable to get the rollback feature as java.util.logging.Logger doesn't support it.
What are the possible options for me to implement?
Is it possible to generate rollback logs automatically using the same library?
Code :
private static class MyCustomFormatterforUpdate extends java.util.logging.Formatter {
#Override
public String format(LogRecord record) {
StringBuffer sb = new StringBuffer();
sb.append("update ApiStatistics set RespDateTime =");
sb.append(record.getMessage());
sb.append(";");
sb.append("\n");
return sb.toString();
}
}
java.util.logging.Logger updatefile = java.util.logging.Logger.getLogger("Update Script");
boolean appendu = false;
FileHandler fhu;
{
try {
fhu = new FileHandler("src/main/resources/updatescript.log",appendu);
updatefile.addHandler(fhu);
fhu.setFormatter(new MyCustomFormatterforUpdate());
} catch (IOException e) {
e.printStackTrace();
}
}
Building upon my previous answer you just need to build out the proxy implementation inferred in that answer. The idea is to install a proxy handler which allows you to open and close the FileHandler object. This enabled the rotation you need. Below is working example that will rotate when the date changes. The test case is included and the output will appear in the home folder by default.
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.logging.ErrorManager;
import java.util.logging.FileHandler;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.logging.XMLFormatter;
public class DailyFileHandler extends Handler {
public static void main(String[] args) throws IOException {
DailyFileHandler dfh = new DailyFileHandler();
try {
dfh.setFormatter(new SimpleFormatter());
LogRecord r1 = new LogRecord(Level.SEVERE, "test 1");
LogRecord r2 = new LogRecord(Level.SEVERE, "test 2");
r2.setMillis(r1.getMillis() + (24L * 60L * 60L * 1000L));
dfh.publish(r1);
dfh.publish(r2);
} finally {
dfh.close();
}
}
private Calendar current = Calendar.getInstance();
private FileHandler target;
public DailyFileHandler() throws IOException {
target = new FileHandler(pattern(), limit(), count(), false);
init();
}
public DailyFileHandler(String pattern, int limit, int count)
throws IOException {
target = new FileHandler(pattern, limit, count, false);
init();
}
private void init() {
super.setLevel(level());
super.setFormatter(formatter());
super.setFilter(filter());
try {
super.setEncoding(encoding());
} catch (UnsupportedEncodingException impossible) {
throw new AssertionError(impossible);
}
initTarget();
}
private void initTarget() {
target.setErrorManager(super.getErrorManager());
target.setLevel(super.getLevel());
target.setFormatter(super.getFormatter());
target.setFilter(super.getFilter());
try {
target.setEncoding(super.getEncoding());
} catch (UnsupportedEncodingException impossible) {
throw new AssertionError(impossible);
}
}
private void rotate() {
String pattern = pattern();
int count = count();
int limit = limit();
try {
super.setErrorManager(target.getErrorManager());
target.close();
FileHandler rotate = new FileHandler(pattern, 0, count, false);
rotate.setFormatter(new SimpleFormatter()); //empty tail.
rotate.close();
current = Calendar.getInstance();
target = new FileHandler(pattern, limit, count, true);
initTarget();
} catch (RuntimeException | IOException e) {
this.reportError("", e, ErrorManager.OPEN_FAILURE);
}
}
private boolean shouldRotate(long millis) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
return cal.get(Calendar.DAY_OF_YEAR) != current.get(Calendar.DAY_OF_YEAR);
}
#Override
public synchronized void publish(LogRecord record) {
if (shouldRotate(record.getMillis())) {
rotate();
}
target.publish(record);
}
#Override
public synchronized void close() throws SecurityException {
target.close();
}
#Override
public synchronized void setEncoding(String encoding) throws SecurityException, UnsupportedEncodingException {
target.setEncoding(encoding);
super.setEncoding(encoding);
}
#Override
public synchronized boolean isLoggable(LogRecord record) {
return target.isLoggable(record);
}
#Override
public synchronized void flush() {
target.flush();
}
#Override
public synchronized void setFormatter(Formatter newFormatter) {
target.setFormatter(newFormatter);
super.setFormatter(newFormatter);
}
#Override
public synchronized Formatter getFormatter() {
return target.getFormatter();
}
#Override
public synchronized String getEncoding() {
return target.getEncoding();
}
#Override
public synchronized void setFilter(Filter newFilter) throws SecurityException {
target.setFilter(newFilter);
super.setFilter(newFilter);
}
#Override
public synchronized Filter getFilter() {
return target.getFilter();
}
#Override
public synchronized void setErrorManager(ErrorManager em) {
target.setErrorManager(em);
super.setErrorManager(em);
}
#Override
public synchronized ErrorManager getErrorManager() {
return target.getErrorManager();
}
#Override
public synchronized void setLevel(Level newLevel) throws SecurityException {
target.setLevel(newLevel);
super.setLevel(newLevel);
}
#Override
public synchronized Level getLevel() {
return target.getLevel();
}
private String pattern() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String pattern = m.getProperty(p + ".pattern");
if (pattern == null) {
pattern = "%h/java%u.log";
}
return pattern;
}
private int limit() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".limit");
int limit = v == null ? Integer.MAX_VALUE : Integer.parseInt(v);
return limit;
}
private int count() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".count");
int limit = v == null ? 7 : Integer.parseInt(v);
return limit;
}
private Level level() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".level");
if (v != null) {
try {
return Level.parse(v);
} catch (Exception e) {
this.reportError(v, e, ErrorManager.OPEN_FAILURE);
}
}
return Level.ALL;
}
private Formatter formatter() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".formatter");
if (v != null) {
try {
return Formatter.class.cast(Class.forName(v).newInstance());
} catch (Exception e) {
this.reportError("", e, ErrorManager.OPEN_FAILURE);
}
}
return new XMLFormatter();
}
private Filter filter() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".filter");
if (v != null) {
try {
return Filter.class.cast(Class.forName(v).newInstance());
} catch (Exception e) {
this.reportError("", e, ErrorManager.OPEN_FAILURE);
}
}
return null;
}
private String encoding() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".encoding");
if (v != null) {
try {
return Charset.forName(v).name();
} catch (Exception e) {
this.reportError(v, e, ErrorManager.OPEN_FAILURE);
}
}
return null;
}
}
A suggestion would be please use other logging frameworks which has many features in them
instead of java.util.logging.Logger
Useful links
configure-log4j-for-creating-daily-rolling-log-files
log4j-formatting-examples
a-guide-to-logging-in-java
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 6 years ago.
The purpose of the class below is to get text from different articles of different news websites. The version below is designed for Android, but it throws a NetworkOnMainThread Exception when run. When I used an earlier version of this class, made specifically to run on a computer, it worked fine, but I'm not really sure how network I/O works on Android. I've seen some other answers to questions about this topic, but I don't understand why in Android the program throws an exception but on a desktop it works fine. Can anyone explain?
package com.example.user.helloworld;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class ArticleReceiver {
private ArrayList<Article> newsArticles = new ArrayList<>();
private ArrayList<String> newsLinks = new ArrayList<>();
public ArticleReceiver(int numArticles, String link) {
if (numArticles != 0) {
receiveNewsArticles(numArticles, link);
}else{
System.out.println("ERROR: numArticles request for " + link + " cannot equal 0.");
}
}
private void receiveNewsArticles(int numArticles, String urlAddress) {
URL rssUrl = null;
// if connected to Internet
if (true){//isInternetAvailable()) {
try {
// gather links
rssUrl = new URL(urlAddress);
BufferedReader in = new BufferedReader(new InputStreamReader(rssUrl.openStream()));
String line;
// fix bbc trash urls
if (urlAddress.equals(Main.BBC_URL)) {
numArticles++;
}
while ((line = in.readLine()) != null && newsLinks.size() <= numArticles) {
if (line.contains("<link>")) {
// find links through tags
int firstPos = line.indexOf("<link>");
String temp = line.substring(firstPos);
temp = temp.replace("<link>", "");
int lastPos = temp.indexOf("</link>");
temp = temp.substring(0, lastPos);
newsLinks.add(temp);
}
}
in.close();
// test if there are links and if there is remove first
// unnecessary
// link
if (!newsLinks.isEmpty()) {
if (urlAddress.equals(Main.BBC_URL)) {
newsLinks.remove(0);
newsLinks.remove(0);
}else if(urlAddress.equals(Main.CNN_URL) || urlAddress.equals(Main.FOX_URL) || urlAddress.equals(Main.ESPN_URL)){
newsLinks.remove(0);
}
} else {
System.out.println("ERROR: No Found Articles. Check If You Have Wifi.");
}
// gather articles from HTML "section" or "p" tag of article using Jsoup
for (String newsLink : newsLinks) {
// get webpage
Document doc = Jsoup.connect(newsLink).get();
// get article from different websites
String article = null;
if (urlAddress.equals(Main.FOX_URL)) {
Elements element = doc.select("p");
article = element.text();
} else if (urlAddress.equals(Main.CNN_URL)) {
Elements element = doc.select("section");
article = element.text();
} else if (urlAddress.equals(Main.BBC_URL)) {
Elements element = doc.select("p");
article = element.text();
}else if(urlAddress.equals(Main.ESPN_URL)){
Elements element = doc.select("p");
article = element.text();
}
newsArticles.add(new Article(article, Main.SUMMARY_SENTENCES));
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("ERROR: No internet connection established.");
return;
}
}
public ArrayList<Article> getArticles() {
return newsArticles;
}
public Article getArticle(int i) {
if (newsArticles.size() <= i) {
return null;
} else {
return newsArticles.get(i);
}
}
//The method below does not recognize the "getSystemService" method, and when the method is no longer present there is a NetworkOnMainThreadException
private boolean isInternetAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
You need to execute web service connections asynchronous.
What I use in my projects is have a class ApiConnection and with interface get response. Example:
Apiconnection class
public class APIConnection extends AsyncTask<Object, String, Void> {
private final String TAG = "API-CONNECTION";
private StringBuilder sbuilder;
private JSONObject json;
private APIConnectionInterface mInterface;
protected int httpResponseCode = 0;
private String entity = null, url;
private APIConnectionType mmode;
private boolean DEBUG = BuildConfig.DEBUG;
private String[][] headers;
/**
Constructor For APIConnection
*/
public APIConnection(APIConnectionInterface thisdelegate, APIConnectionType mode, String murl, String entity) {
this.mInterface = thisdelegate;
this.mmode = mode;
this.url = murl;
this.entity = entity;
initHeaders();
}
private void initHeaders(){
headers = new String[][]{
{"token", "MY_TOKEN"},
{"Content-Type", "application/json;charset=utf-8"},
{"user-agent", "android"},
{"Accept-Language", "es"}
};
}
#Override
protected Void doInBackground(Object... params) {
BufferedReader buffer = null;
InputStreamReader in = null;
OutputStream os = null;
int timeoutConnection = 30000, timeoutSocket = 20000;
try{
sbuilder = new StringBuilder();
url = convertURL(url);
if (entity==null)entity="{}";
URL u = new URL(url);
HttpURLConnection conn;
if (url.startsWith("https://"))
conn = (HttpsURLConnection) u.openConnection();
else
conn = (HttpURLConnection) u.openConnection();
conn.setReadTimeout(timeoutConnection);
conn.setConnectTimeout(timeoutSocket);
for (String[] arr : headers){ conn.addRequestProperty(arr[0], arr[1]); }
/*GET*/if (mmode == APIConnectionType.GET) {
conn.setDoInput(true);
conn.setRequestMethod(mmode.toString());
httpResponseCode = conn.getResponseCode();
in = new InputStreamReader(
httpResponseCode == HttpURLConnection.HTTP_OK ? conn.getInputStream() : conn.getErrorStream(),"UTF-8");
/*OTHER*/} else if (mmode == APIConnectionType.POST || mmode == APIConnectionType.PUT ||
mmode == APIConnectionType.PATCH || mmode == APIConnectionType.DELETE) {
conn.setRequestMethod(mmode.toString());
conn.setDoOutput(true);
byte[] outputInBytes = entity.getBytes("UTF-8");
os = conn.getOutputStream();
os.write( outputInBytes );
httpResponseCode = conn.getResponseCode();
in = new InputStreamReader(
httpResponseCode == HttpURLConnection.HTTP_OK ? conn.getInputStream() : conn.getErrorStream(), "UTF-8");
}
if (in!=null){
buffer=new BufferedReader(in);
String line;
while ((line = buffer.readLine()) != null) {
sbuilder.append(line);
}
}else {
sbuilder.append("");
}
}
catch(IOException e) {
if (DEBUG)Log.d(TAG, "onBackground Exception " + e.getMessage());
sbuilder= new StringBuilder();
httpResponseCode = 0;
cancel(true);
return null;
} finally {
if (buffer != null) {
try {
buffer.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (os!=null){
try {
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result){
try{
if (DEBUG) timelapse_e = System.currentTimeMillis();
if (sbuilder != null) {
json = new JSONObject(sbuilder.toString());
}
if (sbuilder != null){
sbuilder.setLength(0);
sbuilder.trimToSize();
}
sbuilder = null;
GoRunning();
hideDialog();
}
catch(RuntimeException e) {
if (DEBUG)Log.d(TAG, "PostExecute RuntimeException " + e.getMessage());
cancel(true);
}
catch(Exception e) {
if (DEBUG)Log.d(TAG, "PostExecute Exception " + e.getMessage());
cancel(true);
}
}
#Override protected void onCancelled() {
if (mInterface != null) mInterface.onCancelled(APIConnection.this);
super.onCancelled();
}
#Override protected void onPreExecute() {
super.onPreExecute();
if (DEBUG) timelapse_s = System.currentTimeMillis();
if (mInterface != null) mInterface.onStartLoading(APIConnection.this);
}
public void GoRunning(){
if (mInterface != null) try {
mInterface.onDataArrival(APIConnection.this, json, httpResponseCode);
} catch (JSONException e) {
onCancelled();
e.printStackTrace();
}
}
/**
* Hide Dialog (Progress dialog) if is showing and activity NOT Finishing
*/
private void hideDialog() {
if (mInterface != null) mInterface.onFinishedLoading(APIConnection.this);
}
/** <b>convertURL(String str);</b><br/>
* replaces any special characters to <b>%??</b><br/>
* Replacements actived:<br/>
* "{Space}" ==> "%20"
* #param str URL to encode
* #return url encoded
*/
public static String convertURL(String str) {
return str.trim().replace(" ", "%20");
// .replace("&", "%26")
// .replace(",", "%2c").replace("(", "%28").replace(")", "%29")
// .replace("!", "%21").replace("=", "%3D").replace("<", "%3C")
// .replace(">", "%3E").replace("#", "%23").replace("$", "%24")
// .replace("'", "%27").replace("*", "%2A").replace("-", "%2D")
// .replace(".", "%2E").replace("/", "%2F").replace(":", "%3A")
// .replace(";", "%3B").replace("?", "%3F").replace("#", "%40")
// .replace("[", "%5B").replace("\\", "%5C").replace("]", "%5D")
// .replace("_", "%5F").replace("`", "%60").replace("{", "%7B")
// .replace("|", "%7C").replace("}", "%7D"));
}
public interface APIConnectionInterface {
void onDataArrival(APIConnection apiConnection, JSONObject json, int httpResponseCode) throws JSONException;
void onStartLoading(APIConnection apiConnection);
void onFinishedLoading(APIConnection apiConnection);
void onCancelled(APIConnection apiConnection);
}
public enum APIConnectionType {
GET("GET"),
POST("POST"),
PUT("PUT"),
PATCH("PATCH"),
DELETE("DELETE");
private String methodName;
APIConnectionType(String methodName){this.methodName = methodName;}
#Override public String toString() {return methodName;}
}
}
And then from any Activity or Fragment I can call the web service async
like this:
new APIConnection(new APIConnection.APIConnectionInterface() {
#Override public void onDataArrival(APIConnection apiConnection, JSONObject json, int httpResponseCode) {
try {
if (isHttpResponseOk(httpResponseCode, json)){//200 or 201
JSONObject obj = json.getJSONObject("results");
// do things with json
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override public void onStartLoading(APIConnection apiConnection) {showProgressDialog();}
#Override public void onFinishedLoading(APIConnection apiConnection) {hideProgressDialog();}
#Override public void onCancelled(APIConnection apiConnection) {hideProgressDialog();}
}, APIConnection.APIConnectionType.GET, MyApp.API_URL + "/master_data/", null).execute();
The only thing you need is to adapt the response to other object you need.
I hope that helps
I am trying to write a java program that reads in an XML file and returns various elements of interest to the user. I am having some issues getting it to compile and I have created a test class in order for it to be displayed properly. This is what I have thus far.
EDIT: The Bolded Line in the test class is giving me problems. The error is cannot convert from String to Resources.
public class T_Resources {
public static void main(String[] args) {
Resources resources = ResourceImporter.importResourcesFromXML("http://free1.ed.gov/xml/gemexport.xml");
displayResources(resources);
}
private static void displayResources(Resources resources) {
Subject[] subjects;
**Resources resource = resources.getTitle();**
System.out.println(resource.getTitle());
System.out.println(resource.getDescription());
System.out.println(resource.getIdentifier());
subjects = resource.getSubjects();
for (int i=0; i < subjects.length; ++i) {
System.out.println(subjects[i].getCategory() + " :: " + subjects[i].getSubcategory());
}
System.out.println();
}
}
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ResourceImporter {
// This operation loads the XML document specified by the document location, which can a file or a URL,
// and returns a reference to the document. If the operation cannot successfully load the document
// the operation returns the null reference.
//
private static Document loadXMLDocument(String documentLocation) {
// The XML document.
//
Document documentIn = null;
// The parser that reads in an XML files.
//
DocumentBuilder parser = null;
// Pull the document
//
try {
// Obtain a document parser.
//
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
parser = builderFactory.newDocumentBuilder();
documentIn = parser.parse(documentLocation);
} catch (ParserConfigurationException p) {
System.out.println("Error creating parser.");
System.out.println(" " + p.getMessage());
} catch (SAXException s) {
System.out.println("Document is not well formed.");
System.out.println(" " + s.getMessage());
} catch (IOException i) {
System.out.println("Error accessing the file.");
System.out.println(" " + i.getMessage());
} catch (Exception e) {
System.out.println("Unknown error occurred.");
System.out.println(" " + e.getMessage());
}
return documentIn;
}
public static Resources importResourcesFromXML(String documentLocation) {
Resources resource = new Resources();
Document doc;
Element resourceElement;
Element titleElement;
String title;
Element descriptionElement;
String description;
Element identifierElement;
String identifiers;
Element urlElement;
String url;
NodeList subjectList;
Element subjectElement;
String subjects;
Element categoryElement;
String category;
Element subcategoryElement;
String subcategory;
doc = loadXMLDocument(documentLocation);
resourceElement = (Element)doc.getElementsByTagName("resource").item(0);
if (resourceElement != null) {
titleElement = (Element)resourceElement.getElementsByTagName("title").item(0);
resource.setTitle( titleElement == null ? "unknown" : titleElement.getTextContent() );
descriptionElement = (Element)resourceElement.getElementsByTagName("description").item(0);
resource.setDescription( descriptionElement == null ? "unknown" : descriptionElement.getTextContent() );
identifierElement = (Element)resourceElement.getElementsByTagName("identifier").item(0);
if (identifierElement != null) {
Identifier identifier = new Identifier();
urlElement = (Element)identifierElement.getElementsByTagName("url").item(0);
identifier.setURL( urlElement == null ? "unknown" : urlElement.getTextContent() );
subjectElement = (Element)resourceElement.getElementsByTagName("subjects").item(0);
if (subjectElement != null) {
subjectList = subjectElement.getElementsByTagName("subject");
for (int i=0; i < subjectList.getLength(); ++i) {
Subject subject = new Subject();
subjectElement = (Element)subjectList.item(i);
categoryElement = (Element)subjectElement.getElementsByTagName("category").item(0);
subject.setCategory( categoryElement == null ? "unknown" : categoryElement.getTextContent() );
subcategoryElement = (Element)subjectElement.getElementsByTagName("subcategory").item(0);
subject.setSubcategory( subcategoryElement == null ? "unknown" :subcategoryElement.getTextContent() );
resource.addSubject(subject);
}
}
}
}
return resource;
}
}
public class Resources {
private static final int MAX_SUBJECTS = 20;
private String title;
private String description;
private Identifier identifier;
private Subject[] subjects;
private int subjectCount;
public Resources() {
title = "unknown title";
description = "unknown description";
identifier = null;
subjects = new Subject[MAX_SUBJECTS];
subjectCount = 0;
}
public void setTitle(String newTitle) {
title = newTitle;
}
public String getTitle() {
return title;
}
public void setDescription(String newDescription) {
description = newDescription;
}
public String getDescription() {
return description;
}
public void setIdentifier(Identifier newIdentifier) {
identifier = newIdentifier;
}
public Identifier getIdentifier() {
return identifier;
}
public void addSubject(Subject newSubject) {
subjects[subjectCount++] = newSubject;
}
public Subject[] getSubjects() {
Subject[] result = new Subject[subjectCount];
System.arraycopy(subjects, 0, result, 0, subjectCount);
return result;
}
}
public class Subject {
private String category;
private String subcategory;
public Subject() {
String category = "unknown";
String subcategory = "unknown";
}
public Subject(Subject subject) {
category = subject.category;
subcategory = subject.subcategory;
}
public void setCategory(String newCategory) {
category = (newCategory == null) ? "unknown" : newCategory;
}
public String getCategory() {
return category;
}
public void setSubcategory(String newSubcategory) {
subcategory = newSubcategory;
}
public String getSubcategory() {
return subcategory;
}
}
public class Identifier {
private String url;
public Identifier() {
url = "unknown";
}
public void setURL(String newURL) {
url = newURL;
}
public String getURL() {
return url;
}
}
The error lies in here:
private static void displayResources(Resources resources) {
Subject[] subjects;
// DELETE THIS
// **Resources resource = resources.getTitle();**
// RENAME 'resource' to 'resources', or just change the method parameter above...
System.out.println(resources.getTitle());
//System.out.println(resource.getTitle());
System.out.println(resources.getDescription());
//System.out.println(resource.getDescription());
System.out.println(resources.getIdentifier());
//System.out.println(resource.getIdentifier());
....
You pass a Resources Object, and normally you would want to work directly with it?
Currently this just seems borked here, all the other code works, I tested and get fancy console outputs.
EDIT: (Answering a comment below this post.)
In ResourceImporter.java add line following the comment below:
if (resourceElement != null) {
titleElement = (Element)resourceElement.getElementsByTagName("title").item(0);
resource.setTitle( titleElement == null ? "unknown" : titleElement.getTextContent() );
descriptionElement = (Element)resourceElement.getElementsByTagName("description").item(0);
resource.setDescription( descriptionElement == null ? "unknown" : descriptionElement.getTextContent() );
identifierElement = (Element)resourceElement.getElementsByTagName("identifier").item(0);
if (identifierElement != null) {
Identifier identifier = new Identifier();
urlElement = (Element)identifierElement.getElementsByTagName("url").item(0);
identifier.setURL( urlElement == null ? "unknown" : urlElement.getTextContent() );
// ADDED THIS LINE HERE
resource.setIdentifier(identifier);
subjectElement = (Element)resourceElement.getElementsByTagName("subjects").item(0);
if (subjectElement != null) {
subjectList = subjectElement.getElementsByTagName("subject");
....
You may also want to use this line for your syso's in the helper method being used in the main method: System.out.println(resources.getIdentifier().getURL());, otherwise you will get uninterpretable information.
I'd change
private static void displayResources(Resources resources)
to
private static void displayResources(Resources resource)
(notice I removed the 's'), and remove your bold line.
As stated by JB Nizet, your method returns a String when you want the Resources that is passed to your static method.
The getTitle() method is declared as
public String getTitle()
But you're assigning its result to a variabe of type Resources:
Resources resource = resources.getTitle();
That obviously can't work, hence the error, which is quite self-explanatory:
cannot convert from String to Resources
You probably want
String title = resources.getTitle();
instead.