/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016, 2019 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.midp.protocol;
import java.io.*;
import java.util.*;
import javax.microedition.io.*;
import javax.wireless.messaging.*;
import malik.emulator.io.j2me.*;
public class SupportedConnections extends Object
implements Runnable, VirtualConnectionFactory
{
public static final int DEFAULT_PORT_FOR_RECEIVE_WIRELESS_MESSAGES = 1200;
private InboundConnection[] inboundConnections;
private QueueOfObjects events;
private URLParser urlParser;
public SupportedConnections()
{
this.inboundConnections = new InboundConnection[2];
this.events = new QueueOfObjects(16);
this.urlParser = new URLParser();
(new Thread(this, "Обработчик событий от соединений")).start();
openDefaultConnections();
}
public void closeConnection(Connection connection)
throws IOException
{
int i;
if(connection instanceof InboundConnection)
{
synchronized(events)
{
if((i = indexOfInboundConnection(connection)) >= 0)
{
inboundConnections[i] = null;
}
}
}
}
public void registerConnection(String url, String midlet, String filter)
throws IOException, ClassNotFoundException
{
}
public boolean unregisterConnection(String url)
{
return false;
}
public boolean platformRequest(String url)
throws ConnectionNotFoundException
{
return false;
}
public int checkPermission(String permission)
{
return PERMISSION_ALLOWED;
}
public String[] listConnections(boolean available)
{
return null;
}
public String getFilter(String url)
{
return null;
}
public String getMIDlet(String url)
{
return null;
}
public Connection openConnection(String url, int mode, boolean timeouts)
throws IOException
{
int remotePort;
String protocol;
String userInfo;
String remoteHost;
String remotePath;
String remoteQuery;
URLParser parser;
Connection result;
(parser = urlParser).parse(url);
protocol = parser.getProtocol();
userInfo = parser.getUserInfo();
remoteHost = parser.getHostName();
remotePort = parser.getPort();
remotePath = parser.getPath();
remoteQuery = parser.getQuery();
if((result = openConnection(url, protocol, userInfo, remoteHost, remotePort, remotePath,
remoteQuery, mode, timeouts)) instanceof InboundConnection)
{
checkAndRegisterInboundConnection(protocol, remotePort, (InboundConnection) result);
}
return result;
}
public final void run()
{
Runnable event;
QueueOfObjects events = this.events;
do
{
waitEvent();
if(events.isEmpty())
{
continue;
}
synchronized(events)
{
event = (Runnable) events.peek();
events.removeTailElement();
}
try
{
event.run();
}
catch(Throwable e)
{
e.printRealStackTrace();
}
} while(true);
}
public final void setEvent(Runnable event)
{
QueueOfObjects events;
synchronized(events = this.events)
{
events.push(event);
events.notify();
}
}
public final InboundConnection getInboundConnection(String protocol, int localPort)
{
int i;
InboundConnection[] c;
InboundConnection result;
InboundConnection connection;
String connectionProtocol;
if(protocol == null)
{
return null;
}
for(result = null, i = (c = inboundConnections).length; i-- > 0; )
{
try
{
if((connection = c[i]) != null &&
(connectionProtocol = connection.getProtocol()) != null &&
protocol.equalsIgnoreCase(connectionProtocol) &&
localPort == connection.getLocalPort())
{
result = connection;
break;
}
}
catch(IOException e)
{
/* проигнорировать исключение */
}
}
return result;
}
protected void openDefaultConnections()
{
MessageConnection defaultMessagePort;
try
{
(defaultMessagePort = (MessageConnection) openConnection("sms://:" +
DEFAULT_PORT_FOR_RECEIVE_WIRELESS_MESSAGES, MODE_READ_WRITE, false)).
setMessageListener(new WirelessMessageDefaultPortListener(defaultMessagePort));
}
catch(IOException e)
{
e.printRealStackTrace();
}
}
protected Connection openConnection(String url, String protocol, String userInfo,
String remoteHost, int remotePort, String remotePath, String remoteQuery,
int mode, boolean timeouts)
throws IOException
{
Connection result;
label0:
{
if("file".equalsIgnoreCase(protocol))
{
if((mode & MODE_READ_WRITE) != MODE_READ)
{
throw new IOException("Connector.open: " +
"неподдерживаемый режим открытия (протокол file).");
}
if((userInfo == null || userInfo.length() <= 0) &&
(remoteHost == null || remoteHost.length() <= 0) &&
remotePort == URLParser.EMPTY_PORT &&
(remoteQuery == null || remoteQuery.length() <= 0))
{
if(remotePath == null || remotePath.length() <= 0)
{
remotePath = "/";
}
result = new malik.emulator.midp.protocol.file.ReadOnlyFileConnection(
url, remotePath);
break label0;
}
throw new IllegalArgumentException("Connector.open: " +
"недопустимый адрес (протокол file).");
}
else if("resource".equalsIgnoreCase(protocol))
{
if((mode & MODE_READ_WRITE) != MODE_READ)
{
throw new IOException("Connector.open: " +
"неподдерживаемый режим открытия (протокол resource).");
}
if((userInfo == null || userInfo.length() <= 0) &&
(remoteHost == null || remoteHost.length() <= 0) &&
remotePort == URLParser.EMPTY_PORT &&
(remoteQuery == null || remoteQuery.length() <= 0))
{
if(remotePath == null || remotePath.length() <= 0)
{
remotePath = "/";
}
result = new malik.emulator.midp.protocol.resource.ReadOnlyResourceConnection(
url, remotePath);
break label0;
}
throw new IllegalArgumentException("Connector.open: " +
"недопустимый адрес (протокол resource).");
}
else if("sms".equalsIgnoreCase(protocol))
{
if((userInfo == null || userInfo.length() <= 0) &&
(remotePath == null || remotePath.length() <= 0) &&
(remoteQuery == null || remoteQuery.length() <= 0))
{
if(remoteHost != null && remoteHost.length() > 0)
{
result = new malik.emulator.midp.protocol.sms.ClientMessageConnection(
url);
break label0;
}
if(remotePort >= 0)
{
result = new malik.emulator.midp.protocol.sms.ServerMessageConnection(
url, remotePort);
break label0;
}
}
throw new IllegalArgumentException("Connector.open: " +
"недопустимый адрес (протокол sms).");
}
else
{
throw new ConnectionNotFoundException("Connector.open: " +
"неизвестный протокол " + protocol);
}
}
return result;
}
protected final void checkAndRegisterInboundConnection(String protocol,
int localPort, InboundConnection inboundConnection)
throws IOException
{
boolean found;
int i;
int len;
int freedIndex;
InboundConnection[] c;
InboundConnection connection;
String connectionProtocol;
if(protocol == null || inboundConnection == null)
{
return;
}
synchronized(events)
{
found = false;
freedIndex = -1;
for(i = len = (c = inboundConnections).length; i-- > 0; )
{
if((connection = c[i]) == null)
{
freedIndex = i;
continue;
}
try
{
if((connectionProtocol = connection.getProtocol()) != null &&
protocol.equalsIgnoreCase(connectionProtocol) &&
localPort == connection.getLocalPort())
{
found = true;
break;
}
}
catch(IOException e)
{
e.printRealStackTrace();
}
}
if(!found)
{
if(freedIndex < 0)
{
Array.copy(c, 0, c = inboundConnections =
new InboundConnection[(freedIndex = len) << 1], 0, freedIndex);
}
c[freedIndex] = inboundConnection;
}
}
if(found)
{
throw new IOException("Connector.open: " +
"локальный порт " + localPort + " по протоколу " + protocol +
" уже занят.");
}
}
protected final URLParser getURLParser()
{
return urlParser;
}
private void waitEvent()
{
Object monitor;
synchronized(monitor = events)
{
do
{
try
{
monitor.wait();
break;
}
catch(InterruptedException e)
{
e.printRealStackTrace();
}
} while(true);
}
}
private int indexOfInboundConnection(Connection connection)
{
int i;
Connection[] c;
for(i = (c = inboundConnections).length; i-- > 0; )
{
if(connection == c[i])
{
return i;
}
}
return -1;
}
}