/* * Copyright (c) 2006-2017 DMDirc Developers * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.dmdirc.parser.common; import com.dmdirc.parser.events.ParserErrorEvent; import com.dmdirc.parser.interfaces.ChannelInfo; import com.dmdirc.parser.interfaces.ClientInfo; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.ProxySelector; import java.net.SocketAddress; import java.net.URI; import java.net.URISyntaxException; import java.time.LocalDateTime; import java.util.List; import net.engio.mbassy.bus.error.PublicationError; /** * Implements common base functionality for parsers. *
* Implementations of this class must be annotated with {@link ChildImplementations} to define
* the implementations to use for instances of {@link ClientInfo}, {@link ChannelInfo}, etc.
*/
public abstract class BaseParser extends ThreadedParser {
private final Object errorHandlerLock = new Object();
/** The URI that this parser was constructed for. */
private final URI uri;
/** The ignore list for this parser. */
private IgnoreList ignoreList;
/** The ping timer interval for this parser. */
private long pingTimerInterval;
/** The ping timer fraction for this parser. */
private int pingTimerFraction;
/** The cached name of the server this parser is connected to. */
private String serverName;
/** The IP that this parser should bind to. */
private String bindIp;
/** The IPv6 IP that this parser should bind to. */
private String bindIpv6;
/** The URI of the proxy to use when connecting, if any. */
private URI proxy;
/** The callback manager to use for this parser. */
private final CallbackManager callbackManager;
/**
* Creates a new base parser for the specified URI.
*
* @param uri The URI this parser will connect to.
*/
public BaseParser(final URI uri) {
this.uri = uri;
callbackManager = new CallbackManager(this::handleCallbackError);
}
@SuppressWarnings({
"ThrowableResultOfMethodCallIgnored",
"CallToPrintStackTrace",
"UseOfSystemOutOrSystemErr"
})
private void handleCallbackError(final PublicationError e) {
if (Thread.holdsLock(errorHandlerLock)) {
// ABORT ABORT ABORT - we're publishing an error on the same thread we just tried
// to publish an error on. Something in the error reporting pipeline must be
// breaking, so don't try adding any more errors.
System.err.println("ERROR: Error when reporting error");
e.getCause().printStackTrace();
return;
}
synchronized (errorHandlerLock) {
callbackManager.publish(new ParserErrorEvent(this, LocalDateTime.now(), e.getCause()));
}
}
@Override
public void quit(final String reason) {
disconnect(reason);
}
@Override
public URI getURI() {
return uri;
}
@Override
public URI getProxy() {
if (proxy == null && ProxySelector.getDefault() != null) {
final List