Executing URI commands in Java - java

One way that Steam lets users launch games and perform many other operations, is by using URI protocols, for example (from Valve developer community):
steam://run/<id> will launch the game that corresponds to the specified ID.
steam://validate/<id> will validate the game files of the specified ID.
How can I get Java to 'run' these? I don't even know what you call it, i.e. do you 'run' URIs, or 'execute' them, or what? Because persumably these URIs don't have anything to return, and the URI class in Java doesn't have anything related to 'executing' them, however URL does, but it doesn't work!
I've tried this:
...
try
{
URI testURI = URI.create("steam://run/240");
URL testURL = joinURI.toURL();
// URL testURL = new URL("steam://run/240") doesn't work either
joinURL.openConnection(); // Doesn't work
// joinURL.openStream() doesn't work either
}
catch (MalformedURLException e)
{
System.err.println(e.getMessage());
}
...
Each combination gives the error: unknown protocol: steam.
The system that Steam uses to handle the URIs is definitely working, because for example, I can type the above URI into Firefox and it works.
My eternal gratitude to the person who provides the answer!
Thanks

Try Desktop.browse(URI), this should start the "default action" which is the Steam client for a steam:// URI, e.g.
URI uri = new URI("steam://store/240");
if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(uri);
}

The system that Steam uses to handle the URIs is definitely working, because for example, I can type the above URI into Firefox and it works.
It is working because Firefox (or other browsers) can associate unkown protocols with applications. When you load steam://xxx for the first time, Firefox asks you which application you want to open. If it didn't ask you, steam probably installed a browser plugin for that.

A Uniform Resource Identifier (URI) just identifies a resource, it doesn't necessarily describe how to access it. Moreover, for custom protocols, such as "steam" the vendor can define any underlying access conventions which compatible client programs must know to interact.
In order to "execute" a URI like this you need to know exactly how the protocol is implemented (is it over HTTP? TCP? UDP?) and how to speak with the server at the other end.
The Valve Developer Community wiki page might have some useful information.

Related

Change REST URL depending on called URL

I currently have a problem with a REST service: The basic construction is the following: On my Tomcat there are running 2 applications (my new REST service (S1) and another application (S2) which also offers REST calls). The Applications should work together so that S1 can send requests to S2. It works fine if I use hard coded URLs in S1 to call S2. But the problem is that the path of the applications are changing due to different ports or configurations. The changes apply to both applications since they are both on the same Tomcat server.
Basically the 2 Paths look similar, starting e.g. with http://localhost:8080/ or http://sys-example:8034/. So if I call S1 on an specific Path, the application should fetch the URL and build its own basePath to reach S2 on the same Server. How can I create a method which gets me the path where my service is called. IS there a way to use ServletContext or is there a better way?
Currently this is my code in S1 to reach the service in S2
String path = configMap.get("basePath").toString();
//configMap is a HashMap which contains Data from an config file
//the result of get("basePath") looks like this: http://localhost:8080
path = path.concat("/otherService/rest/action/login");
If you are sure that the 2 servlets will run in the same Tomcat installation and, moreover, in the same context, I suggest using the direct interaction.
Please check the link at this URL.
If I got you right, you are saying that you run the services in different environments, e.g. production, development, local etc., which means host and port differ. The relative paths to your services remain the same, though.
Then, it is absolutely ok to hard-code the relative paths since they don't change. The host and port, however, should be configurable. You could load them from the database, in case you have access to your database before you need those data.
Another solution might be to configure host and port within your web container. If you should use Tomcat as your web container, create a properties file and load it when the app is being bootstrapped.
EDIT:
Other answers suggest to resolve the path from the request object. I disadvise doing that for the following reasons:
There might be use cases where you don't have a request. There might be (now or in future) other interfaces to your services than via HTTP
You should not rely on what URL to call depending on the request coming in, since you have no control over that values. Think of Reverse Proxies or Load Balancer.
You can extract the REST call using an URI object. Example:
URI u = URI.create("http://www.example.com:8080/rest/service/call");
String restPath = u.getPath();
System.out.println(restPath);
This way, you can append the REST url easily to S2. I hope that helps :)
You can fetch the required details from HttpServletRequest object.
The below code must give you the required details. I have not tested this, but this should get you started.
StringBuffer url = request.getRequestURL();
String uri = request.getRequestURI();
String host = url.substring(0, url.indexOf(uri));
I think request.getRequestURL() is what you want

Lotus Notes Java API. Mail forwarding

I would like to forward emails from my Lotus Notes inbox to my gmail account.
Lotus Notes rules and agents are disabled on our server, so I developed external application for that.
I am using document.send method and mail successfully arrives to my gmail box.
The only problem is that often the email also duplicated in my Lotus Notes inbox.
I just found that the reason of that is "CC" and "BCC" fields, which I don't clean up,
however, I am looking for the way to forward email as it is - which means keep original CC and BCC and TO fields - exactly on the same way as it is done by forwarding agent.
I am using "IBM Notes 9" on Windows 7 64 bit.
I've prepared a code sample that demonstrates what I am doing.
package com.example;
import lotus.domino.*;
public class TestMailForwarder {
public static void main(String[] args) throws NotesException {
NotesThread.sinitThread();
try {
Session notesSession = NotesFactory.createSession(
(String) null, (String) null, Consts.NOTES_PASSWORD);
DbDirectory dir = notesSession.getDbDirectory(Consts.NOTES_SERVER);
Database mailDb = dir.openDatabaseByReplicaID(Consts.MAILDB_REPLICA_ID);
forwardAllEmails(mailDb);
} finally {
NotesThread.stermThread();
}
}
private static void forwardAllEmails(Database mailDb) throws NotesException {
View inbox = mailDb.getView("$Inbox");
//noinspection LoopStatementThatDoesntLoop
for (Document document = inbox.getFirstDocument();
null != document;
document = inbox.getNextDocument(document)) {
document.send(Consts.GMAIL_ADDRESS);
break;
}
}
}
Instead of trying to send the messages to your GMail, why not upload them using Gmail's IMAP interface. You would require to get the message as MIME content - which probably they are already for external incoming eMails and then push them to GMail.
I don't have a ready code sample, just one for the opposite pulling GMail into Notes, but you should be able to use that as a starting point.
A code sample for the MIME conversion is in an IBM Technote.
Hope that helps
You can't do a transparent forward with code running at the client level. Pure SMTP systems do it by preserving the RFC-822 header content while altering the RFC-821 RCPT TO data. Domino does not give client-level code independent control over these. It just uses the SendTo, CopyTo, and BlindCopyTo items. (There are some tricks that mail management and archiving vendors play in order to do things like this, but they require special changes to the Domino server's router configuration, and software on the other end as well.
Another way of accomplishing this (in response to the question you asked in your comment) would be to have your Java code make a direct connection to the gmail SMTP servers. I'm not sure how easy it is. A comment on this question states that the Java Mail API allows you to control the RCPT TO separately from the RFC822 headers, but I've not looked into the specifics other than taking note that there's an SMTPTransport class -- which is where I'd look for anything related to RFC-821 protocol. The bigger issue is that you will have to take control of converting messages into MIME format. With Notes mail, you may have a mix of Notes rich text and MIME. Theres a convertToMIME method in Notes 8.5.1 and above, but this will only convert the message body. You'll have to deal with any header content separately. (I'm not really up to speed on Notes 9, but AFAIK even though there is functionality in the client to create a .EML file when you drag a message to the desktop, there's no API there to do that for you.)
Finally, I've found a ready solution: AWESYNC.MAIL.
It is a commercial software but it does exactly what I need.

How do I change the port used for livetribe SLP?

I'm attempting to use LiveTribe SLP module (http://livetribe.codehaus.org/LiveTribe-SLP) to provide an SLP service for an application. I want to change the port from 427 to something else entirely. The documentation is sparse and even more confusing is that in the FAQ, it claims to link to an example that would show me exactly what I'm looking for. Unfortunately, it doesn't (unless I'm overlooking something). Does anyone know how to do this?
There is a client and server example here:
http://livetribe.org/SLP-Examples-JMX
(Link broken.)
These are the important lines on the server side:
// Allow this code to be run by non-root users on Linux/Unix
Settings settings = new MapSettings();
settings.put(Keys.PORT_KEY, 4427);
// Create the SLP ServiceAgent that advertises the JMX service
ServiceAgent serviceAgent = SLP.newServiceAgent(settings);
And on the client side:
// Allow this code to be run by non-root users on Linux/Unix
Settings settings = new MapSettings();
settings.put(Keys.PORT_KEY, 4427);
// Create the SLP UserAgentClient that discovers services
UserAgentClient userAgentClient = SLP.newUserAgentClient(settings);
Sorry about the bad documentation. We've had problems with it ever since we changed the L&F of the site to use Twitter Bootstrap.
The page should now fully render:
http://livetribe.org/SLP-Examples-JMX
Link broken.

Java User Agent

I have recently started seeing user agents like Java/1.6.0_14 (and variations) on my site
What does this mean. Is it a browser or bot or what
This likely means someone is crawling your website using Java. This isn't much of anything to be concerned about unless you notice the crawler using large amounts of your bandwidth or not respecting your robots.txt file. Usually legitimate crawlers will take the time to create custom user agent to make it easy to contact the crawler if you have a problem, but even if they're using the default user agent, it's more than likely perfectly benign.
However, if you do notice a spike in 404 hits or lots of hits from the Java client, you're likely under attack by spammers looking for security holes in your website. If your site is built well, there's not a whole lot they can do other than burn some of your bandwidth, but if they find a security hole, they'll be sure to exploit it. Dealing with spammers properly is beyond the scope of this answer, but a scorched earth solution (which will work as a short term fix at the very least) would be to block all user agents that contain the string 'java'.
It means your site is being accessed through the JVM on someones machine. It could be a crawler or simply someone scraping data. You can replicate the user-agent string using the HttpURLConnection class. Here is a sample:
import java.net.*;
public class Request {
public static void main(String[] args) {
try {
URL url=new URL("http://google.ca");
HttpURLConnection con=(HttpURLConnection)url.openConnection();
con.connect();
System.out.println(con.getResponseCode());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java's HttpURLConnection class will send the JVM version information as the User-Agent header.

Java Servlet: How to handle unknown encodings?

When a certain user tries to view our web page, a NullPointerException with the message 'charsetName' is thrown when we call response.getWriter(). I decompiled our web server's response class (JRun 3.1) and found that this error is being thrown when it does this:
s = getCharacterEncoding(); // returns 'x-mac-roman' I believe
try
{
outWriter.exchangeWriter(new OutputStreamWriter(bufStream, s));
}
catch(UnsupportedEncodingException unsupportedencodingexception)
{
s = MIME2Java.convert(s); // looks like this returns null
outWriter.exchangeWriter(new OutputStreamWriter(bufStream, s)); // NPE!!!
}
I was finally able to reproduce this bug when I forced my browser to send a request header of 'Accept-Charset=x-mac-roman,utf-8', which is what the user's browser seems to do.
This is webserver code so I can't make any changes here, but this there something we can do on our end to ensure this never happens. Can we explicitly force the webserver to use a certain encoding and not leave it up to the requests?
MacRoman is an "international character set" which is not always installed by the Sun Java installer, and hence not available to the programs.
According to http://java.sun.com/javase/6/docs/technotes/guides/intl/encoding.doc.html it is not done if the installer determines it is an "European" operating system.
If you reinstall your Sun Java and request support for Non-European languages in a customized installation, this should be corrected.
You can create a filter and a new Request (using a request wrapper) that always responds a "valid" character encoding, for assorted values of "valid". Effectively, that's what they're trying to do with the MIME2Java.convert() call, but you would have to do that "early" and intercept that to ensure that you have better control over the encoding.

Categories