mirror of
https://github.com/Rogiel/httpchannel
synced 2025-12-05 23:22:51 +00:00
Implements several services and improves API
This commit is contained in:
@@ -59,8 +59,8 @@
|
||||
<groupId>org.htmlparser</groupId>
|
||||
<artifactId>htmlparser</artifactId>
|
||||
<version>2.1</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<name>HttpChannel/Service/Utilities</name>
|
||||
<description>Module providing several utilities to service implementations. Though this module is not required to implement services, it contains several shortcuts that can help implementing services.</description>
|
||||
</project>
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.rogiel.httpchannel.captcha;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractImageCaptcha implements ImageCaptcha {
|
||||
private final URL imageURL;
|
||||
private final String ID;
|
||||
|
||||
private String answer;
|
||||
private boolean automaticallyResolved;
|
||||
|
||||
public AbstractImageCaptcha(URL imageURL, String ID) {
|
||||
this.imageURL = imageURL;
|
||||
this.ID = ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnswer(String answer) {
|
||||
this.answer = answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnswer() {
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasAutomaticallyResolved() {
|
||||
return automaticallyResolved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getImageURL() {
|
||||
return imageURL;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return ID;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.rogiel.httpchannel.captcha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import com.rogiel.httpchannel.http.GetRequest;
|
||||
import com.rogiel.httpchannel.http.HttpContext;
|
||||
import com.rogiel.httpchannel.http.PostMultipartRequest;
|
||||
import com.rogiel.httpchannel.http.PostRequest;
|
||||
import com.rogiel.httpchannel.util.htmlparser.HTMLPage;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractImageCaptchaService<C extends AbstractImageCaptcha>
|
||||
implements ImageCaptchaService<C> {
|
||||
protected final HttpContext http = new HttpContext();
|
||||
|
||||
@Override
|
||||
public final C create(String html) {
|
||||
try {
|
||||
return create(HTMLPage.parse(html));
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract C create(HTMLPage page) throws IOException;
|
||||
|
||||
@Override
|
||||
public boolean resolve(C captcha) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public GetRequest get(String url) {
|
||||
return http.get(url);
|
||||
}
|
||||
|
||||
public GetRequest get(URL url) {
|
||||
return http.get(url);
|
||||
}
|
||||
|
||||
public PostRequest post(String url) {
|
||||
return http.post(url);
|
||||
}
|
||||
|
||||
public PostMultipartRequest multipartPost(String url) {
|
||||
return http.multipartPost(url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.rogiel.httpchannel.http;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
||||
public class GetRequest extends Request {
|
||||
private long position = 0;
|
||||
|
||||
public GetRequest(HttpContext ctx, String url) {
|
||||
super(ctx, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse request() throws IOException {
|
||||
final HttpGet get = new HttpGet(url);
|
||||
if (position > 0)
|
||||
get.addHeader("Range", "bytes=" + position + "-");
|
||||
return ctx.client.execute(get);
|
||||
}
|
||||
|
||||
public GetRequest position(long position) {
|
||||
this.position = position;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.rogiel.httpchannel.http;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class HttpContext {
|
||||
protected final ExecutorService threadPool = Executors
|
||||
.newCachedThreadPool();
|
||||
/**
|
||||
* The {@link HttpClient} instance for this service
|
||||
*/
|
||||
protected DefaultHttpClient client = new DefaultHttpClient();
|
||||
|
||||
public GetRequest get(String url) {
|
||||
return new GetRequest(this, url);
|
||||
}
|
||||
|
||||
public GetRequest get(URL url) {
|
||||
return get(url.toString());
|
||||
}
|
||||
|
||||
public PostRequest post(String url) {
|
||||
return new PostRequest(this, url);
|
||||
}
|
||||
|
||||
public PostMultipartRequest multipartPost(String url) {
|
||||
return new PostMultipartRequest(this, url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.rogiel.httpchannel.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.mime.MultipartEntity;
|
||||
import org.apache.http.entity.mime.content.ContentBody;
|
||||
import org.apache.http.entity.mime.content.StringBody;
|
||||
|
||||
import com.rogiel.httpchannel.service.channel.LinkedUploadChannel;
|
||||
import com.rogiel.httpchannel.service.channel.LinkedUploadChannelContentBody;
|
||||
|
||||
public class PostMultipartRequest extends PostRequest {
|
||||
private final MultipartEntity entity;
|
||||
|
||||
public PostMultipartRequest(HttpContext ctx, String url) {
|
||||
super(ctx, url);
|
||||
this.entity = new MultipartEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse request() throws IOException {
|
||||
final HttpPost post = new HttpPost(url);
|
||||
post.setEntity(entity);
|
||||
return ctx.client.execute(post);
|
||||
}
|
||||
|
||||
public PostMultipartRequest parameter(String name, ContentBody body) {
|
||||
entity.addPart(name, body);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PostMultipartRequest parameter(String name, String value)
|
||||
throws UnsupportedEncodingException {
|
||||
return parameter(name, new StringBody(value));
|
||||
}
|
||||
|
||||
public PostMultipartRequest parameter(String name,
|
||||
LinkedUploadChannel channel) {
|
||||
return parameter(name, new LinkedUploadChannelContentBody(channel));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.rogiel.httpchannel.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
public class PostRequest extends Request {
|
||||
protected final List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
|
||||
public PostRequest(HttpContext ctx, String url) {
|
||||
super(ctx, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpResponse request() throws IOException {
|
||||
final HttpPost post = new HttpPost(url);
|
||||
post.setEntity(new UrlEncodedFormEntity(params));
|
||||
return ctx.client.execute(post);
|
||||
}
|
||||
|
||||
public PostRequest parameter(String name, String value)
|
||||
throws UnsupportedEncodingException {
|
||||
params.add(new BasicNameValuePair(name, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public PostRequest parameter(String name, int value)
|
||||
throws UnsupportedEncodingException {
|
||||
return parameter(name, Integer.toString(value));
|
||||
}
|
||||
|
||||
public PostRequest parameter(String name, boolean value)
|
||||
throws UnsupportedEncodingException {
|
||||
return parameter(name, (value ? "1" : "0"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package com.rogiel.httpchannel.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
|
||||
import com.rogiel.httpchannel.util.HttpClientUtils;
|
||||
import com.rogiel.httpchannel.util.htmlparser.HTMLPage;
|
||||
|
||||
public abstract class Request {
|
||||
protected final HttpContext ctx;
|
||||
protected final String url;
|
||||
|
||||
public Request(HttpContext ctx, String url) {
|
||||
this.ctx = ctx;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public abstract HttpResponse request() throws IOException;
|
||||
|
||||
public Future<HttpResponse> requestAsync() throws IOException {
|
||||
return ctx.threadPool.submit(new Callable<HttpResponse>() {
|
||||
@Override
|
||||
public HttpResponse call() throws Exception {
|
||||
return request();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String asString() throws ClientProtocolException, IOException {
|
||||
return HttpClientUtils.toString(request());
|
||||
}
|
||||
|
||||
public Future<String> asStringAsync() throws IOException {
|
||||
return ctx.threadPool.submit(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return asString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HTMLPage asPage() throws ClientProtocolException, IOException {
|
||||
return HTMLPage.parse(asString());
|
||||
}
|
||||
|
||||
public Future<HTMLPage> asPageAsync() throws IOException {
|
||||
return ctx.threadPool.submit(new Callable<HTMLPage>() {
|
||||
@Override
|
||||
public HTMLPage call() throws Exception {
|
||||
return asPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getURL() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import com.rogiel.httpchannel.service.Authenticator.AuthenticatorConfiguration;
|
||||
|
||||
/**
|
||||
* An abstract {@link Authenticator} that implements most of the general-purpose
|
||||
* methods
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <C>
|
||||
* the {@link Authenticator} configuration object type
|
||||
*/
|
||||
public abstract class AbstractAuthenticator<C extends AuthenticatorConfiguration>
|
||||
implements Authenticator<C> {
|
||||
protected final Credential credential;
|
||||
/**
|
||||
* The {@link Authenticator} configuration
|
||||
*/
|
||||
protected final C configuration;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param credential
|
||||
* the authentication credential
|
||||
* @param configuration
|
||||
* the configuration object
|
||||
*/
|
||||
protected AbstractAuthenticator(Credential credential, C configuration) {
|
||||
this.credential = credential;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public C getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +1,79 @@
|
||||
/*
|
||||
* This file is part of seedbox <github.com/seedbox>.
|
||||
*
|
||||
* seedbox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* seedbox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with seedbox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
|
||||
import com.rogiel.httpchannel.util.ThreadUtils;
|
||||
|
||||
/**
|
||||
* @author rogiel
|
||||
*/
|
||||
public abstract class AbstractDownloader implements Downloader {
|
||||
protected int parseTimer(String stringTimer) {
|
||||
int timer = 0;
|
||||
if (stringTimer != null && stringTimer.length() > 0) {
|
||||
timer = Integer.parseInt(stringTimer);
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
|
||||
protected long getContentLength(HttpResponse response) {
|
||||
final Header contentLengthHeader = response
|
||||
.getFirstHeader("Content-Length");
|
||||
long contentLength = -1;
|
||||
if (contentLengthHeader != null) {
|
||||
contentLength = Long.valueOf(contentLengthHeader.getValue());
|
||||
}
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
protected void timer(DownloadListener listener, long timer) {
|
||||
if (listener != null) {
|
||||
listener.timer(timer);
|
||||
}
|
||||
ThreadUtils.sleep(timer);
|
||||
}
|
||||
}
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration;
|
||||
import com.rogiel.httpchannel.service.channel.InputStreamDownloadChannel;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadLimitExceededException;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadLinkNotFoundException;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadNotAuthorizedException;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadNotResumableException;
|
||||
|
||||
/**
|
||||
* An abstract {@link Downloader} that implements most of the general-purpose
|
||||
* methods
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <C>
|
||||
* the {@link Downloader} configuration object type
|
||||
*/
|
||||
public abstract class AbstractDownloader<C extends DownloaderConfiguration>
|
||||
implements Downloader<C> {
|
||||
/**
|
||||
* The download URL
|
||||
*/
|
||||
protected final URL url;
|
||||
|
||||
/**
|
||||
* The {@link Downloader} configuration
|
||||
*/
|
||||
protected final C configuration;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param url
|
||||
* the download url
|
||||
* @param configuration
|
||||
* the configuration object
|
||||
*/
|
||||
protected AbstractDownloader(URL url, C configuration) {
|
||||
this.url = url;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadChannel openChannel(long position) throws IOException,
|
||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||
DownloadNotAuthorizedException, DownloadNotResumableException {
|
||||
return openChannel(null, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadChannel openChannel(DownloadListener listener)
|
||||
throws IOException, DownloadLinkNotFoundException,
|
||||
DownloadLimitExceededException, DownloadNotAuthorizedException,
|
||||
DownloadNotResumableException {
|
||||
return openChannel(listener, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DownloadChannel openChannel() throws IOException,
|
||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||
DownloadNotAuthorizedException, DownloadNotResumableException {
|
||||
return openChannel(null, 0);
|
||||
}
|
||||
|
||||
protected InputStreamDownloadChannel createInputStreamChannel(
|
||||
InputStream in, long length, String filename) {
|
||||
return new InputStreamDownloadChannel(in, length, filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public C getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of seedbox <github.com/seedbox>.
|
||||
*
|
||||
* seedbox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* seedbox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with seedbox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
|
||||
import com.rogiel.httpchannel.http.Request;
|
||||
import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration;
|
||||
import com.rogiel.httpchannel.service.channel.InputStreamDownloadChannel;
|
||||
import com.rogiel.httpchannel.util.ThreadUtils;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
||||
extends AbstractDownloader<C> implements Downloader<C> {
|
||||
protected AbstractHttpDownloader(URL url, C configuration) {
|
||||
super(url, configuration);
|
||||
}
|
||||
|
||||
protected long getContentLength(HttpResponse response) {
|
||||
final Header contentLengthHeader = response
|
||||
.getFirstHeader("Content-Length");
|
||||
long contentLength = -1;
|
||||
if (contentLengthHeader != null) {
|
||||
contentLength = Long.valueOf(contentLengthHeader.getValue());
|
||||
}
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
protected void timer(DownloadListener listener, long timer) {
|
||||
if (listener != null) {
|
||||
if (!listener.timer(timer))
|
||||
return;
|
||||
}
|
||||
ThreadUtils.sleep(timer);
|
||||
}
|
||||
|
||||
protected InputStreamDownloadChannel download(Request request)
|
||||
throws IOException {
|
||||
final HttpResponse response = request.request();
|
||||
final String filename = FilenameUtils.getName(request.getURL());
|
||||
final long contentLength = getContentLength(response);
|
||||
return createInputStreamChannel(response.getEntity().getContent(),
|
||||
contentLength, filename);
|
||||
}
|
||||
}
|
||||
@@ -16,151 +16,47 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import com.rogiel.httpchannel.service.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.service.config.ServiceConfiguration;
|
||||
import com.rogiel.httpchannel.util.AlwaysRedirectStrategy;
|
||||
import com.rogiel.httpchannel.util.HttpClientUtils;
|
||||
import com.rogiel.httpchannel.util.htmlparser.HTMLPage;
|
||||
import com.rogiel.httpchannel.http.GetRequest;
|
||||
import com.rogiel.httpchannel.http.HttpContext;
|
||||
import com.rogiel.httpchannel.http.PostMultipartRequest;
|
||||
import com.rogiel.httpchannel.http.PostRequest;
|
||||
import com.rogiel.httpchannel.service.channel.LinkedUploadChannel;
|
||||
import com.rogiel.httpchannel.util.ThreadUtils;
|
||||
|
||||
/**
|
||||
* Abstract base service for HTTP enabled services.
|
||||
*
|
||||
* @author Rogiel
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class AbstractHttpService<T extends ServiceConfiguration>
|
||||
extends AbstractService<T> implements Service {
|
||||
private static final ExecutorService threadPool = Executors
|
||||
.newCachedThreadPool();
|
||||
public abstract class AbstractHttpService extends AbstractService implements
|
||||
Service {
|
||||
protected final HttpContext http = new HttpContext();
|
||||
|
||||
/**
|
||||
* The {@link HttpClient} instance for this service
|
||||
*/
|
||||
protected DefaultHttpClient client = new DefaultHttpClient();
|
||||
|
||||
/**
|
||||
* The captcha resolver
|
||||
*/
|
||||
protected CaptchaResolver captchaResolver;
|
||||
|
||||
protected AbstractHttpService(T configuration) {
|
||||
super(configuration);
|
||||
client.setRedirectStrategy(new AlwaysRedirectStrategy());
|
||||
// client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS,
|
||||
// true);
|
||||
// client.getParams().setIntParameter(ClientPNames.MAX_REDIRECTS, 10);
|
||||
// client.setRedirectStrategy(new DefaultRedirectStrategy());
|
||||
protected LinkedUploadChannel waitChannelLink(LinkedUploadChannel channel,
|
||||
Future<?> future) {
|
||||
while (!channel.isLinked() && !future.isDone()) {
|
||||
ThreadUtils.sleep(100);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
protected HttpResponse get(String url) throws ClientProtocolException,
|
||||
IOException {
|
||||
final HttpGet request = new HttpGet(url);
|
||||
return client.execute(request);
|
||||
public GetRequest get(String url) {
|
||||
return http.get(url);
|
||||
}
|
||||
|
||||
protected HttpResponse get(String url, long rangeStart)
|
||||
throws ClientProtocolException, IOException {
|
||||
final HttpGet request = new HttpGet(url);
|
||||
if (rangeStart >= 0)
|
||||
request.addHeader("Range", "bytes=" + rangeStart + "-");
|
||||
return client.execute(request);
|
||||
public GetRequest get(URL url) {
|
||||
return http.get(url);
|
||||
}
|
||||
|
||||
protected String getAsString(String url) throws ClientProtocolException,
|
||||
IOException {
|
||||
return HttpClientUtils.toString(get(url));
|
||||
public PostRequest post(String url) {
|
||||
return http.post(url);
|
||||
}
|
||||
|
||||
protected HTMLPage getAsPage(String url) throws ClientProtocolException,
|
||||
IOException {
|
||||
return HTMLPage.parse(getAsString(url));
|
||||
}
|
||||
|
||||
public Future<HttpResponse> getAsync(final String url) throws IOException {
|
||||
return threadPool.submit(new Callable<HttpResponse>() {
|
||||
@Override
|
||||
public HttpResponse call() throws Exception {
|
||||
return get(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Future<String> getAsStringAsync(final String url) throws IOException {
|
||||
return threadPool.submit(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return getAsString(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Future<HTMLPage> getAsPageAsync(final String url) throws IOException {
|
||||
return threadPool.submit(new Callable<HTMLPage>() {
|
||||
@Override
|
||||
public HTMLPage call() throws Exception {
|
||||
return getAsPage(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected HttpResponse post(String url, HttpEntity entity)
|
||||
throws ClientProtocolException, IOException {
|
||||
final HttpPost request = new HttpPost(url);
|
||||
request.setEntity(entity);
|
||||
return client.execute(request);
|
||||
}
|
||||
|
||||
protected String postAsString(String url, HttpEntity entity)
|
||||
throws ClientProtocolException, IOException {
|
||||
return HttpClientUtils.toString(post(url, entity));
|
||||
}
|
||||
|
||||
protected HTMLPage postAsPage(String url, HttpEntity entity)
|
||||
throws ClientProtocolException, IOException {
|
||||
return HTMLPage.parse(postAsString(url, entity));
|
||||
}
|
||||
|
||||
protected Future<HttpResponse> postAsync(final String url,
|
||||
final HttpEntity entity) throws IOException {
|
||||
return threadPool.submit(new Callable<HttpResponse>() {
|
||||
@Override
|
||||
public HttpResponse call() throws Exception {
|
||||
return post(url, entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected Future<String> postAsStringAsync(final String url,
|
||||
final HttpEntity entity) throws IOException {
|
||||
return threadPool.submit(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return postAsString(url, entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected Future<HTMLPage> postAsPageAsync(final String url,
|
||||
final HttpEntity entity) throws IOException {
|
||||
return threadPool.submit(new Callable<HTMLPage>() {
|
||||
@Override
|
||||
public HTMLPage call() throws Exception {
|
||||
return postAsPage(url, entity);
|
||||
}
|
||||
});
|
||||
public PostMultipartRequest multipartPost(String url) {
|
||||
return http.multipartPost(url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.rogiel.httpchannel.service;
|
||||
|
||||
import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration;
|
||||
import com.rogiel.httpchannel.service.channel.LinkedUploadChannel;
|
||||
import com.rogiel.httpchannel.service.channel.LinkedUploadChannel.LinkedUploadChannelCloseCallback;
|
||||
|
||||
/**
|
||||
* An abstract {@link Uploader} that implements most of the general-purpose
|
||||
* methods
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <C>
|
||||
* the {@link Uploader} configuration object type
|
||||
*/
|
||||
public abstract class AbstractUploader<C extends UploaderConfiguration>
|
||||
implements Uploader<C> {
|
||||
protected final String filename;
|
||||
protected final long filesize;
|
||||
|
||||
/**
|
||||
* The {@link Uploader} configuration
|
||||
*/
|
||||
protected final C configuration;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param filename
|
||||
* the file name
|
||||
* @param filesize
|
||||
* the file size
|
||||
* @param configuration
|
||||
* the configuration object
|
||||
*/
|
||||
public AbstractUploader(String filename, long filesize, C configuration) {
|
||||
this.filename = filename;
|
||||
this.filesize = filesize;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new linked channel
|
||||
*
|
||||
* @param closeCallback
|
||||
* the close callback
|
||||
* @return a newly created {@link LinkedUploadChannel}
|
||||
*/
|
||||
protected LinkedUploadChannel createLinkedChannel(
|
||||
LinkedUploadChannelCloseCallback closeCallback) {
|
||||
return new LinkedUploadChannel(closeCallback, filesize, filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public C getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,12 @@
|
||||
package com.rogiel.httpchannel.service.channel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import com.rogiel.httpchannel.service.UploadChannel;
|
||||
|
||||
import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
@@ -33,7 +34,7 @@ public class LinkedUploadChannel implements UploadChannel {
|
||||
|
||||
private final long length;
|
||||
private final String filename;
|
||||
private String downloadLink;
|
||||
private URL downloadLink;
|
||||
|
||||
private boolean open = true;
|
||||
|
||||
@@ -59,7 +60,10 @@ public class LinkedUploadChannel implements UploadChannel {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
open = false;
|
||||
downloadLink = closeCallback.finish();
|
||||
final String downloadLink = closeCallback.finish();
|
||||
if (downloadLink == null)
|
||||
throw new UploadLinkNotFoundException();
|
||||
this.downloadLink = new URL(downloadLink);
|
||||
}
|
||||
|
||||
public interface LinkedUploadChannelCloseCallback {
|
||||
@@ -77,12 +81,12 @@ public class LinkedUploadChannel implements UploadChannel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadLink() {
|
||||
public URL getDownloadLink() {
|
||||
return downloadLink;
|
||||
}
|
||||
|
||||
public void linkChannel(WritableByteChannel channel) throws IOException {
|
||||
if(this.channel != null)
|
||||
if (this.channel != null)
|
||||
throw new IOException("This channel is already linked.");
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.rogiel.httpchannel.service.Uploader;
|
||||
/**
|
||||
* {@link ContentBody} used to upload files in {@link Uploader} implementations.
|
||||
*
|
||||
* @author Rogiel
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
public class LinkedUploadChannelContentBody extends AbstractContentBody {
|
||||
|
||||
@@ -16,14 +16,23 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import com.rogiel.httpchannel.service.UploadChannel;
|
||||
import com.rogiel.httpchannel.service.UploadService;
|
||||
import com.rogiel.httpchannel.service.helper.UploadServices;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class ChannelUtils {
|
||||
public static void copy(ReadableByteChannel in, WritableByteChannel out)
|
||||
@@ -48,4 +57,24 @@ public class ChannelUtils {
|
||||
buffer.compact();
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(ReadableByteChannel channel)
|
||||
throws IOException {
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
copy(channel, Channels.newChannel(out));
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static URL upload(UploadService<?> service, Path path)
|
||||
throws IOException {
|
||||
final UploadChannel uploadChannel = UploadServices
|
||||
.upload(service, path).openChannel();
|
||||
try {
|
||||
copy(Files.newByteChannel(path, StandardOpenOption.READ),
|
||||
uploadChannel);
|
||||
} finally {
|
||||
uploadChannel.close();
|
||||
}
|
||||
return uploadChannel.getDownloadLink();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package com.rogiel.httpchannel.util;
|
||||
|
||||
/**
|
||||
* @author Rogiel
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
public class ThreadUtils {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
|
||||
public class ContainsFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern content;
|
||||
|
||||
public ContainsFilter(Pattern content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
return content.matcher(node.getText()).find();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
|
||||
public class ContainsInLowerCaseFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern content;
|
||||
|
||||
public ContainsInLowerCaseFilter(Pattern content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
return content.matcher(node.getText().toLowerCase()).find();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.FormTag;
|
||||
|
||||
public class FormActionPatternFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern pattern;
|
||||
|
||||
public FormActionPatternFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof FormTag))
|
||||
return false;
|
||||
final FormTag form = (FormTag) node;
|
||||
return pattern.matcher(form.getFormLocation()).matches();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.nodes.TagNode;
|
||||
|
||||
public class FramePatternFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern pattern;
|
||||
|
||||
public FramePatternFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof TagNode))
|
||||
return false;
|
||||
final TagNode frame = (TagNode) node;
|
||||
if (frame.getAttribute("src") == null)
|
||||
return false;
|
||||
return pattern.matcher(frame.getAttribute("src")).matches();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -23,7 +26,10 @@ import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.Parser;
|
||||
import org.htmlparser.Tag;
|
||||
import org.htmlparser.filters.AndFilter;
|
||||
import org.htmlparser.nodes.TagNode;
|
||||
import org.htmlparser.tags.FormTag;
|
||||
import org.htmlparser.tags.ImageTag;
|
||||
import org.htmlparser.tags.InputTag;
|
||||
import org.htmlparser.tags.LinkTag;
|
||||
import org.htmlparser.tags.ScriptTag;
|
||||
@@ -35,214 +41,208 @@ import org.htmlparser.util.ParserException;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class HTMLPage {
|
||||
private final Parser parser;
|
||||
private final NodeList nodes;
|
||||
|
||||
private HTMLPage(Parser parser) {
|
||||
this.parser = parser;
|
||||
private HTMLPage(Parser parser) throws ParserException {
|
||||
this.nodes = parser.parse(null);
|
||||
}
|
||||
|
||||
public String getLink(final Pattern pattern) {
|
||||
NodeList nodes;
|
||||
private <T extends Node> List<T> filter(final Class<T> nodeType,
|
||||
NodeFilter... filters) {
|
||||
final NodeFilter filter;
|
||||
if (filters.length == 1)
|
||||
filter = filters[0];
|
||||
else
|
||||
filter = new AndFilter(filters);
|
||||
try {
|
||||
nodes = parser.extractAllNodesThatMatch(new NodeFilter() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof LinkTag))
|
||||
return false;
|
||||
final LinkTag link = (LinkTag) node;
|
||||
return pattern.matcher(link.getLink()).matches();
|
||||
}
|
||||
});
|
||||
return list(nodes.extractAllNodesThatMatch(filter, true));
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (nodes.size() >= 1)
|
||||
return ((LinkTag) nodes.elements().nextNode()).getLink();
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getFormAction(final Pattern pattern) {
|
||||
NodeList nodes;
|
||||
try {
|
||||
nodes = parser.extractAllNodesThatMatch(new NodeFilter() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof FormTag))
|
||||
return false;
|
||||
final FormTag form = (FormTag) node;
|
||||
return pattern.matcher(form.getFormLocation()).matches();
|
||||
}
|
||||
});
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends Node> List<T> list(final NodeList list)
|
||||
throws ParserException {
|
||||
final List<T> filtered = new ArrayList<>();
|
||||
final NodeIterator iterator = list.elements();
|
||||
while (iterator.hasMoreNodes()) {
|
||||
filtered.add((T) iterator.nextNode());
|
||||
}
|
||||
if (nodes.size() >= 1)
|
||||
return ((FormTag) nodes.elements().nextNode()).getFormLocation();
|
||||
return null;
|
||||
return filtered;
|
||||
}
|
||||
|
||||
public String getInputValue(final String inputName) {
|
||||
NodeList nodes;
|
||||
try {
|
||||
nodes = parser.extractAllNodesThatMatch(new NodeFilter() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof InputTag))
|
||||
return false;
|
||||
final InputTag input = (InputTag) node;
|
||||
if (!input.getAttribute("name").equals(inputName))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
}
|
||||
if (nodes.size() >= 1)
|
||||
return ((InputTag) nodes.elements().nextNode())
|
||||
.getAttribute("value");
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getIntegerInputValue(final String inputName) {
|
||||
return Integer.parseInt(getInputValue(inputName));
|
||||
}
|
||||
|
||||
public String getInputValue(final Pattern pattern) {
|
||||
NodeList nodes;
|
||||
try {
|
||||
nodes = parser.extractAllNodesThatMatch(new NodeFilter() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof InputTag))
|
||||
return false;
|
||||
final InputTag input = (InputTag) node;
|
||||
if (input.getAttribute("value") == null)
|
||||
return false;
|
||||
if (!pattern.matcher(input.getAttribute("value")).matches())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
}
|
||||
if (nodes.size() >= 1)
|
||||
return ((InputTag) nodes.elements().nextNode())
|
||||
.getAttribute("value");
|
||||
return null;
|
||||
}
|
||||
|
||||
public Tag getTagByID(final String id) {
|
||||
NodeList nodes;
|
||||
try {
|
||||
nodes = parser.extractAllNodesThatMatch(new NodeFilter() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof Tag))
|
||||
return false;
|
||||
if (((Tag) node).getAttribute("id") == null)
|
||||
return false;
|
||||
return ((Tag) node).getAttribute("id").equals(id);
|
||||
}
|
||||
});
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
}
|
||||
if (nodes.size() >= 1)
|
||||
return ((Tag) nodes.elements().nextNode());
|
||||
return null;
|
||||
}
|
||||
|
||||
public Tag getTagByName(final String name) {
|
||||
NodeList nodes;
|
||||
try {
|
||||
nodes = parser.extractAllNodesThatMatch(new NodeFilter() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof Tag))
|
||||
return false;
|
||||
return ((Tag) node).getAttribute("name").equals(name);
|
||||
}
|
||||
});
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
}
|
||||
if (nodes.size() >= 1)
|
||||
return ((Tag) nodes.elements().nextNode());
|
||||
return null;
|
||||
public boolean contains(final Pattern pattern) {
|
||||
return !filter(Node.class, new ContainsFilter(pattern)).isEmpty();
|
||||
}
|
||||
|
||||
public boolean contains(final String text) {
|
||||
try {
|
||||
for (NodeIterator e = parser.elements(); e.hasMoreNodes();) {
|
||||
if (e.nextNode().toPlainTextString().contains(text))
|
||||
return true;
|
||||
}
|
||||
} catch (ParserException e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return contains(Pattern.compile(Pattern.quote(text)));
|
||||
}
|
||||
|
||||
public String findInScript(final Pattern pattern, int n) {
|
||||
NodeList nodes;
|
||||
try {
|
||||
nodes = parser.extractAllNodesThatMatch(new NodeFilter() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public boolean containsIgnoreCase(final String text) {
|
||||
return !filter(
|
||||
Node.class,
|
||||
new ContainsInLowerCaseFilter(Pattern.compile(Pattern
|
||||
.quote(text.toLowerCase())))).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof ScriptTag))
|
||||
return false;
|
||||
final ScriptTag script = (ScriptTag) node;
|
||||
return pattern.matcher(script.getScriptCode()).find();
|
||||
}
|
||||
});
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
}
|
||||
if (nodes.size() >= 1) {
|
||||
final ScriptTag script = (ScriptTag) nodes.elements().nextNode();
|
||||
final Matcher matcher = pattern.matcher(script.getScriptCode());
|
||||
public String find(final Pattern pattern, int n) {
|
||||
for (final Node tag : filter(Tag.class, new ContainsFilter(pattern))) {
|
||||
final Matcher matcher = pattern.matcher(tag.getText());
|
||||
if (matcher.find())
|
||||
return matcher.group(n);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int findIntegerInScript(final Pattern pattern, int n) {
|
||||
String found = findInScript(pattern, n);
|
||||
if(found == null)
|
||||
public int findAsInt(final Pattern pattern, int n) {
|
||||
String found = find(pattern, n);
|
||||
if (found == null)
|
||||
return 0;
|
||||
return Integer.parseInt(findInScript(pattern, n));
|
||||
return Integer.parseInt(findScript(pattern, n));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a link that has an URL following the given pattern
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
* @return the link content, if found. <code>null</code> otherwise
|
||||
*/
|
||||
public String findLink(final Pattern pattern) {
|
||||
for (final LinkTag tag : filter(LinkTag.class, new LinkPatternFilter(
|
||||
pattern))) {
|
||||
return tag.getLink();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a frame that has an URL following the given pattern
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
* @return the iframe url, if found. <code>null</code> otherwise
|
||||
*/
|
||||
public String findFrame(final Pattern pattern) {
|
||||
for (final TagNode tag : filter(TagNode.class, new FramePatternFilter(
|
||||
pattern))) {
|
||||
return tag.getAttribute("src");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a image that has an URL following the given pattern
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
* @return the iframe url, if found. <code>null</code> otherwise
|
||||
*/
|
||||
public String findImage(final Pattern pattern) {
|
||||
for (final ImageTag tag : filter(ImageTag.class,
|
||||
new ImagePatternFilter(pattern))) {
|
||||
return tag.getImageURL();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a form which has an location that respects the given
|
||||
* pattern
|
||||
*
|
||||
* @param pattern
|
||||
* the pattern
|
||||
* @return the URL found, if any. <code>null</code> otherwise
|
||||
*/
|
||||
public String findFormAction(final Pattern pattern) {
|
||||
for (final FormTag tag : filter(FormTag.class,
|
||||
new FormActionPatternFilter(pattern))) {
|
||||
return tag.getFormLocation();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String inputValue(List<InputTag> tags) {
|
||||
for (final InputTag tag : tags) {
|
||||
return tag.getAttribute("value");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getInputValue(final String inputName) {
|
||||
return inputValue(filter(InputTag.class, new InputNameFilter(inputName)));
|
||||
}
|
||||
|
||||
public int getInputValueAsInt(final String inputName) {
|
||||
return Integer.parseInt(getInputValue(inputName));
|
||||
}
|
||||
|
||||
public String getInputValueById(final String id) {
|
||||
return inputValue(filter(InputTag.class, new InputIDFilter(id)));
|
||||
}
|
||||
|
||||
public String getInputValue(final Pattern pattern) {
|
||||
return inputValue(filter(InputTag.class, new InputValuePatternFilter(
|
||||
pattern)));
|
||||
}
|
||||
|
||||
public Tag getTagByID(final String id) {
|
||||
for (final Tag tag : filter(Tag.class, new IDFilter(id))) {
|
||||
return tag;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Tag getTagByName(final String name) {
|
||||
for (final Tag tag : filter(Tag.class, new NameFilter(name))) {
|
||||
return tag;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String findScript(final Pattern pattern, int n) {
|
||||
for (final ScriptTag tag : filter(ScriptTag.class,
|
||||
new ScriptContainsFilter(pattern))) {
|
||||
final Matcher matcher = pattern.matcher(tag.getScriptCode());
|
||||
if (matcher.find())
|
||||
return matcher.group(n);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String findScriptSrc(final Pattern pattern) {
|
||||
for (final ScriptTag tag : filter(ScriptTag.class, new ScriptSrcFilter(
|
||||
pattern))) {
|
||||
final Matcher matcher = pattern.matcher(tag.getAttribute("src"));
|
||||
if (matcher.matches())
|
||||
return matcher.group();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int findScriptAsInt(final Pattern pattern, int n) {
|
||||
String found = findScript(pattern, n);
|
||||
if (found == null)
|
||||
return 0;
|
||||
return Integer.parseInt(found);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
try {
|
||||
for (NodeIterator i = parser.elements(); i.hasMoreNodes();) {
|
||||
builder.append(i.nextNode().toHtml(true));
|
||||
}
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
}
|
||||
return builder.toString();
|
||||
// try {
|
||||
// return parser.parse(null).toHtml(false);
|
||||
// } catch (ParserException e1) {
|
||||
// return null;
|
||||
// }
|
||||
return nodes.toHtml(false);
|
||||
}
|
||||
|
||||
public static HTMLPage parse(String html) {
|
||||
return new HTMLPage(Parser.createParser(html, null));
|
||||
try {
|
||||
return new HTMLPage(Parser.createParser(html, null));
|
||||
} catch (ParserException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.Tag;
|
||||
|
||||
public class IDFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String id;
|
||||
|
||||
public IDFilter(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof Tag))
|
||||
return false;
|
||||
final Tag tag = (Tag) node;
|
||||
if (tag.getAttribute("id") == null)
|
||||
return false;
|
||||
if (!tag.getAttribute("id").equals(id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.ImageTag;
|
||||
|
||||
public class ImagePatternFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern pattern;
|
||||
|
||||
public ImagePatternFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof ImageTag))
|
||||
return false;
|
||||
final ImageTag frame = (ImageTag) node;
|
||||
return pattern.matcher(frame.getImageURL()).matches();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.InputTag;
|
||||
|
||||
public class InputIDFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String id;
|
||||
|
||||
public InputIDFilter(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof InputTag))
|
||||
return false;
|
||||
final InputTag input = (InputTag) node;
|
||||
if (input.getAttribute("id") == null)
|
||||
return false;
|
||||
if (!input.getAttribute("id").equals(id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.InputTag;
|
||||
|
||||
public class InputNameFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String name;
|
||||
|
||||
public InputNameFilter(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof InputTag))
|
||||
return false;
|
||||
final InputTag input = (InputTag) node;
|
||||
if(input.getAttribute("name") == null)
|
||||
return false;
|
||||
if (!input.getAttribute("name").equals(name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.InputTag;
|
||||
|
||||
public class InputValuePatternFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern pattern;
|
||||
|
||||
public InputValuePatternFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof InputTag))
|
||||
return false;
|
||||
final InputTag input = (InputTag) node;
|
||||
if (input.getAttribute("value") == null)
|
||||
return false;
|
||||
if (!pattern.matcher(input.getAttribute("value")).matches())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.LinkTag;
|
||||
|
||||
public class LinkPatternFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern pattern;
|
||||
|
||||
public LinkPatternFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof LinkTag))
|
||||
return false;
|
||||
final LinkTag link = (LinkTag) node;
|
||||
return pattern.matcher(link.getLink()).matches();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.Tag;
|
||||
|
||||
public class NameFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String name;
|
||||
|
||||
public NameFilter(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof Tag))
|
||||
return false;
|
||||
final Tag tag = (Tag) node;
|
||||
if (tag.getAttribute("name") == null)
|
||||
return false;
|
||||
if (!tag.getAttribute("name").equals(name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.ScriptTag;
|
||||
|
||||
public class ScriptContainsFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern pattern;
|
||||
|
||||
public ScriptContainsFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof ScriptTag))
|
||||
return false;
|
||||
final ScriptTag script = (ScriptTag) node;
|
||||
return pattern.matcher(script.getScriptCode()).find();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.rogiel.httpchannel.util.htmlparser;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.htmlparser.Node;
|
||||
import org.htmlparser.NodeFilter;
|
||||
import org.htmlparser.tags.ScriptTag;
|
||||
|
||||
public class ScriptSrcFilter implements NodeFilter {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Pattern pattern;
|
||||
|
||||
public ScriptSrcFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Node node) {
|
||||
if (!(node instanceof ScriptTag))
|
||||
return false;
|
||||
final ScriptTag script = (ScriptTag) node;
|
||||
if (script.getAttribute("src") == null)
|
||||
return false;
|
||||
return pattern.matcher(script.getAttribute("src")).matches();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user