Skip to content
Snippets Groups Projects
Commit 24d925bf authored by Damon Kohler's avatar Damon Kohler
Browse files

Removed old style messaging and switch to new style messages:

- rosjava_messages now generates and contains all messages.
- Messages must be created using MessageFactories.
Renaming for clarity:
- Publishers and subscribers are now TopicParticipants instead of Topics.
- The combination of an identifier and a definition or message declaration are known as declarations.
Lots of other refactoring along the way.
parent fe1fcd8d
Branches
Tags
No related merge requests found
Showing
with 472 additions and 1669 deletions
......@@ -15,7 +15,7 @@
*/
task wrapper(type: Wrapper) {
gradleVersion = '1.0-milestone-8a'
gradleVersion = '1.0-milestone-9'
}
allprojects {
......
......@@ -17,7 +17,7 @@
import org.apache.tools.ant.filters.ReplaceTokens
task javadoc(type: Javadoc) {
javaProjects = rootProject.subprojects.findResults { (it.name != 'docs') ? it : null }
def javaProjects = rootProject.subprojects.findResults { (it.name != 'docs') ? it : null }
source javaProjects.collect { it.sourceSets.main.allJava }
classpath = files(javaProjects.collect { it.sourceSets.main.compileClasspath })
destinationDir = new File("${buildDir}/html", 'javadoc')
......
#Thu Mar 08 09:52:17 CET 2012
#Thu Mar 29 16:06:14 CEST 2012
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.0-milestone-8a-bin.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-1.0-milestone-9-bin.zip
......@@ -9,32 +9,22 @@
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
dependencies {
compile project(':rosjava_bootstrap')
compile project(':rosjava_messages')
compile project(':apache_xmlrpc_common')
compile project(':apache_xmlrpc_server')
compile project(':apache_xmlrpc_client')
compile('ros:message.std_msgs:0.0.0-SNAPSHOT') {
exclude module: 'rosjava_bootstrap'
}
compile('ros:message.rosgraph_msgs:0.0.0-SNAPSHOT') {
exclude module: 'rosjava_bootstrap'
}
compile 'org.jboss.netty:netty:3.2.4.Final'
compile 'com.google.guava:guava:r07'
compile 'dnsjava:dnsjava:2.1.1'
compile 'org.apache.commons:com.springsource.org.apache.commons.logging:1.1.1'
compile 'org.apache.commons:com.springsource.org.apache.commons.net:2.0.0'
testCompile('ros:message.test_ros:0.0.0-SNAPSHOT') {
exclude module: 'rosjava_bootstrap'
}
testCompile('ros:service.test_ros:0.0.0-SNAPSHOT') {
exclude module: 'rosjava_bootstrap'
}
testCompile 'junit:junit:4.8.2'
testCompile 'org.mockito:mockito-all:1.8.5'
}
......
......@@ -20,6 +20,8 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.ros.CommandLineVariables;
import org.ros.EnvironmentVariables;
import org.ros.address.InetAddressFactory;
import org.ros.exception.RosRuntimeException;
import org.ros.namespace.GraphName;
......
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.google.common.base.Preconditions;
public class Description implements XmlSerializable {
static final String DESCRIPTION_TAG = "description";
static final String BRIEF_ATTRIBUTE = "brief";
private String description;
private String brief;
public Description(String description) {
Preconditions.checkNotNull(description);
this.description = description;
this.brief = "";
}
public Description(String description, String brief) {
this(description);
Preconditions.checkNotNull(brief);
this.brief = brief;
}
public Description(Element element) {
Preconditions.checkArgument(element.getNodeName().equals(DESCRIPTION_TAG));
this.description = element.getFirstChild().getNodeValue();
this.brief = element.getAttribute(BRIEF_ATTRIBUTE);
}
public static boolean checkNodeName(Node node) {
return node.getNodeName().equals(DESCRIPTION_TAG);
}
@Override
public Element toElement(Document doc) {
Element element = doc.createElement(DESCRIPTION_TAG);
element.appendChild(doc.createTextNode(description));
if (brief.length() != 0) {
element.setAttribute(BRIEF_ATTRIBUTE, brief);
}
return element;
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import java.util.Map;
import java.util.Map.Entry;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.google.common.collect.Maps;
public class Export implements XmlSerializable {
private final String name;
private final String value;
private final Map<String, String> attributes;
public Export(String name, String value) {
this.name = name;
this.value = value;
attributes = Maps.newHashMap();
}
public void addAttribute(String name, String value) {
attributes.put(name, value);
}
@Override
public Element toElement(Document doc) {
Element element = doc.createElement(name);
for (Entry<String, String> entry : attributes.entrySet()) {
element.setAttribute(entry.getKey(), entry.getValue());
}
element.appendChild(doc.createTextNode(value));
return element;
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import java.net.MalformedURLException;
import java.net.URL;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.google.common.base.Preconditions;
public class License implements XmlSerializable {
private static final String URL_ATTRIBUTE = "url";
private static final String LICENSE_TAG = "license";
private final String license;
private final URL url;
public License(String license, URL url) {
Preconditions.checkNotNull(license);
Preconditions.checkNotNull(url);
this.license = license;
this.url = url;
}
public License(Element element) throws MalformedURLException {
Preconditions.checkArgument(element.getNodeName().equals(LICENSE_TAG));
this.license = element.getFirstChild().getNodeValue();
this.url = new URL(element.getAttribute(URL_ATTRIBUTE));
}
public static boolean checkNodeName(Node node) {
return node.getNodeName().equals(LICENSE_TAG);
}
@Override
public Element toElement(Document doc) {
Element element = doc.createElement(LICENSE_TAG);
element.appendChild(doc.createTextNode(license));
if (url != null) {
element.setAttribute(URL_ATTRIBUTE, url.toString());
}
return element;
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
public class Manifest implements XmlSerializable {
private static final String LOGO_TAG = "logo";
private static final String URL_TAG = "url";
private static final String PACKAGE_TAG = "package";
private static final String AUTHOR_TAG = "author";
private final String type;
private final Collection<Depend> depends;
private final Collection<RosDep> rosdeps;
private final Collection<Export> exports;
private String author;
private License license;
private Description description;
private String logo;
private Review review;
private URL url;
private VersionControl versionControl;
private Manifest() {
type = PACKAGE_TAG;
depends = Lists.newArrayList();
rosdeps = Lists.newArrayList();
exports = Lists.newArrayList();
}
public Manifest(String author, License license) {
this();
Preconditions.checkNotNull(author);
Preconditions.checkNotNull(license);
this.author = author;
this.license = license;
}
public Manifest(Element element) throws MalformedURLException {
this();
Preconditions.checkArgument(element.getNodeName().equals(type));
fromElement(element);
}
public static Manifest parseFromXml(String xml) throws ParserConfigurationException,
SAXException, IOException {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
doc.getDocumentElement().normalize();
return new Manifest(doc.getDocumentElement());
}
public void addDepend(Depend depend) {
depends.add(depend);
}
public boolean removeDepend(Depend depend) {
return depends.remove(depend);
}
public void addRosDep(RosDep rosdep) {
rosdeps.add(rosdep);
}
public boolean removeRosDep(RosDep rosdep) {
return rosdeps.remove(rosdep);
}
public void addExport(Export export) {
exports.add(export);
}
public boolean removeExport(Export export) {
return exports.remove(export);
}
public String getType() {
return type;
}
public Description getDescription() {
return description;
}
public void setDescription(Description description) {
this.description = description;
}
public String getAuthor() {
return author;
}
public License getLicense() {
return license;
}
public Review getReview() {
return review;
}
public void setReview(Review review) {
this.review = review;
}
public String getLogo() {
return logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public URL getUrl() {
return url;
}
public void setUrl(URL url) {
this.url = url;
}
public VersionControl getVersionControl() {
return versionControl;
}
public void setVersionControl(VersionControl versionControl) {
this.versionControl = versionControl;
}
public String toXml() throws ParserConfigurationException, TransformerException {
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(toDocument());
trans.transform(source, result);
return sw.toString();
}
private Document toDocument() throws DOMException, ParserConfigurationException {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
doc.appendChild(toElement(doc));
return doc;
}
@Override
public Element toElement(Document doc) throws ParserConfigurationException {
Element root = doc.createElement(type);
addElementWithText(doc, root, AUTHOR_TAG, author);
root.appendChild(license.toElement(doc));
if (description != null) {
root.appendChild(description.toElement(doc));
}
if (url != null) {
addElementWithText(doc, root, URL_TAG, url.toString());
}
if (logo != null && logo.length() != 0) {
addElementWithText(doc, root, LOGO_TAG, logo);
}
if (versionControl != null) {
root.appendChild(versionControl.toElement(doc));
}
if (review != null) {
root.appendChild(review.toElement(doc));
}
if (!exports.isEmpty()) {
Element exportsElement = addElement(doc, root, "export");
addAll(doc, exportsElement, exports);
}
addAll(doc, root, depends);
addAll(doc, root, rosdeps);
return root;
}
private void addAll(Document doc, Element root, Collection<? extends XmlSerializable> elements)
throws DOMException, ParserConfigurationException {
for (XmlSerializable element : elements) {
root.appendChild(element.toElement(doc));
}
}
private Element addElementWithText(Document doc, Element root, String name, String text) {
Element element = addElement(doc, root, name);
element.appendChild(doc.createTextNode(text));
return element;
}
private Element addElement(Document doc, Element root, String name) {
Element element = doc.createElement(name);
root.appendChild(element);
return element;
}
private void fromElement(Element element) throws MalformedURLException {
Preconditions.checkArgument(element.getNodeName().equals(type));
NodeList nodes = element.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node childNode = nodes.item(i);
Preconditions.checkState(childNode.getNodeType() == Node.ELEMENT_NODE);
String name = childNode.getNodeName();
if (name.equals(AUTHOR_TAG)) {
author = childNode.getFirstChild().getNodeValue();
}
if (License.checkNodeName(childNode)) {
license = new License((Element) childNode);
}
if (Description.checkNodeName(childNode)) {
description = new Description((Element) childNode);
}
if (name.equals(URL_TAG)) {
url = new URL(childNode.getFirstChild().getNodeValue());
}
if (name.equals(LOGO_TAG)) {
logo = childNode.getFirstChild().getNodeValue();
}
if (VersionControl.checkNode(childNode)) {
versionControl = new VersionControl((Element) childNode);
}
if (Review.checkNode(childNode)) {
review = new Review((Element) childNode);
}
}
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class ManifestDepend extends Depend {
private final String package_name;
public ManifestDepend(String package_name) {
this.package_name = package_name;
}
@Override
public Element toElement(Document doc) {
Element element = super.toElement(doc);
element.setAttribute("package", package_name);
return element;
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.google.common.base.Preconditions;
public class Review implements XmlSerializable {
private static final String REVIEW_TAG = "review";
private static final String NOTES_ATTRIBUTE = "notes";
private static final String STATUS_ATTRIBUTE = "status";
private final String status;
private final String notes;
public Review(String status, String notes) {
Preconditions.checkNotNull(status);
Preconditions.checkNotNull(notes);
this.status = status;
this.notes = notes;
}
public Review(Element element) {
Preconditions.checkArgument(element.getNodeName().equals(REVIEW_TAG));
this.status = element.getAttribute(STATUS_ATTRIBUTE);
this.notes = element.getAttribute(NOTES_ATTRIBUTE);
}
public static boolean checkNode(Node node) {
return node.getNodeName().equals(REVIEW_TAG);
}
@Override
public Element toElement(Document doc) {
Element review = doc.createElement(REVIEW_TAG);
review.setAttribute(STATUS_ATTRIBUTE, status);
review.setAttribute(NOTES_ATTRIBUTE, notes);
return review;
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import java.net.MalformedURLException;
import java.net.URL;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.google.common.base.Preconditions;
public class VersionControl implements XmlSerializable {
private static final String VERSION_CONTROL_TAG = "versioncontrol";
private static final String URL_ATTRIBUTE = "url";
private static final String TYPE_ATTRIBUTE = "type";
private final String type;
private final URL url;
public VersionControl(String type, URL url) {
Preconditions.checkNotNull(type);
Preconditions.checkArgument(type.length() != 0);
Preconditions.checkNotNull(url);
this.type = type;
this.url = url;
}
public VersionControl(Element element) throws MalformedURLException {
Preconditions.checkArgument(element.getNodeName().equals(VERSION_CONTROL_TAG));
this.type = element.getAttribute(TYPE_ATTRIBUTE);
this.url = new URL(element.getAttribute(URL_ATTRIBUTE));
}
public static boolean checkNode(Node node) {
return node.getNodeName().equals(VERSION_CONTROL_TAG);
}
@Override
public Element toElement(Document doc) {
Element element = doc.createElement(VERSION_CONTROL_TAG);
element.setAttribute(TYPE_ATTRIBUTE, type);
element.setAttribute(URL_ATTRIBUTE, url.toString());
return element;
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.manifest;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public interface XmlSerializable {
public Element toElement(Document doc) throws ParserConfigurationException;
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.message.new_style;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
// TODO(damonkohler): This should implement org.ros.message.MessageFactory
/**
* Creates {@link MessageImpl} instances.
*
* @author damonkohler@google.com (Damon Kohler)
*/
public class MessageFactory {
private final MessageDefinitionProvider messageDefinitionProvider;
private final DefaultedClassMap<Message> messageClasses;
private final MessageContextFactory messageContextFactory;
public MessageFactory(MessageDefinitionProvider messageDefinitionProvider,
DefaultedClassMap<Message> messageClasses) {
this.messageDefinitionProvider = messageDefinitionProvider;
this.messageClasses = messageClasses;
messageContextFactory = new MessageContextFactory(this);
}
<T> T newProxy(String messageName, String messageDefinition, Class<T> messageClass) {
MessageContext context = messageContextFactory.newFromStrings(messageName, messageDefinition);
return ProxyFactory.newProxy(messageClass, new MessageImpl(context));
}
@SuppressWarnings("unchecked")
public <T extends Message> T newMessage(String messageName) {
MessageContext context =
messageContextFactory.newFromStrings(messageName,
messageDefinitionProvider.get(messageName));
return ProxyFactory.newProxy((Class<T>) messageClasses.get(messageName), new MessageImpl(
context));
}
@SuppressWarnings("unchecked")
public <MessageType extends Message> MessageType deserializeMessage(String messageName,
ByteBuffer buffer) {
buffer.order(ByteOrder.LITTLE_ENDIAN);
MessageType message =
(MessageType) newProxy(messageName, messageDefinitionProvider.get(messageName),
messageClasses.get(messageName));
for (Field field : message.getFields()) {
if (!field.isConstant()) {
field.deserialize(buffer);
}
}
return message;
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.message.new_style;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Collection;
import java.util.Map;
import java.util.Queue;
/**
* @author damonkohler@google.com (Damon Kohler)
*/
public class MessageLoader implements MessageDefinitionProvider {
private static final Log log = LogFactory.getLog(MessageLoader.class);
private static final String STD_MSGS_HEADER_NAME = "std_msgs/Header";
private final Collection<File> searchPaths;
private final Map<String, String> messageDefinitions;
public MessageLoader() {
searchPaths = Sets.newHashSet();
messageDefinitions = Maps.newConcurrentMap();
}
public void addSearchPath(File path) {
searchPaths.add(path);
}
public void updateMessageDefinitions() {
for (File searchPath : searchPaths) {
findMessages(searchPath);
}
}
private final class FindMessagesFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() || pathname.getName().endsWith(".msg");
}
}
private String pathToMessageName(File root, File message) {
String absolutePath = message.getAbsolutePath();
String relativePath =
absolutePath.substring(root.getAbsolutePath().length() - root.getName().length());
String strippedExtension = relativePath.substring(0, relativePath.length() - 4);
String messageName = strippedExtension.replaceFirst("/msg/", "/");
if (messageName.equals(STD_MSGS_HEADER_NAME)) {
return "Header";
}
return messageName;
}
private void findMessages(File searchPath) {
CharsetDecoder decoder = Charset.forName("US-ASCII").newDecoder();
FindMessagesFilter filter = new FindMessagesFilter();
Queue<File> childPaths = Lists.newLinkedList();
childPaths.addAll(listPathEntries(searchPath, filter));
while (!childPaths.isEmpty()) {
File messagePath = childPaths.poll();
if (messagePath.isDirectory()) {
childPaths.addAll(listPathEntries(messagePath, filter));
} else {
try {
addMessageDefinitionFromPaths(searchPath, messagePath, decoder);
} catch (IOException e) {
log.error("Failed to read message: " + messagePath.getAbsolutePath(), e);
}
}
}
}
private void addMessageDefinitionFromPaths(File searchPath, File messagePath,
CharsetDecoder decoder) throws IOException {
FileInputStream inputStream = new FileInputStream(messagePath);
FileChannel channel = inputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate((int) channel.size());
channel.read(buffer);
buffer.rewind();
decoder.reset();
String definition = decoder.decode(buffer).toString().trim();
messageDefinitions.put(pathToMessageName(searchPath, messagePath), definition);
channel.close();
inputStream.close();
}
private Collection<File> listPathEntries(File searchPath, FindMessagesFilter filter) {
File[] entries = searchPath.listFiles(filter);
if (entries == null) {
return Lists.newArrayList();
}
return Lists.newArrayList(entries);
}
@Override
public String get(String messageName) {
return messageDefinitions.get(messageName);
}
@Override
public boolean has(String messageName) {
return messageDefinitions.containsKey(messageName);
}
@VisibleForTesting
ImmutableMap<String, String> getMessageDefinitions() {
return ImmutableMap.copyOf(messageDefinitions);
}
@VisibleForTesting
void addMessageDefinition(String messageName, String messageDefinition) {
messageDefinitions.put(messageName, messageDefinition);
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.message.new_style;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import org.ros.exception.RosRuntimeException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Map;
// TODO(damonkohler): This should be rolled into a org.ros.message.MessageFactory implementation.
/**
* @author damonkohler@google.com (Damon Kohler)
*/
public class ServiceFactory {
private final ServiceLoader serviceLoader;
private final MessageFactory messageFactory;
private final DefaultedClassMap<Service.Request> requestMessageClassRegistry;
private final DefaultedClassMap<Service.Response> responseMessageClassRegistry;
private final Map<String, String> requestDefinitions;
private final Map<String, String> responseDefinitions;
public ServiceFactory(ServiceLoader serviceLoader, MessageFactory messageFactory) {
this.serviceLoader = serviceLoader;
this.messageFactory = messageFactory;
requestMessageClassRegistry = DefaultedClassMap.newFromDefaultClass(Service.Request.class);
responseMessageClassRegistry = DefaultedClassMap.newFromDefaultClass(Service.Response.class);
requestDefinitions = Maps.newConcurrentMap();
responseDefinitions = Maps.newConcurrentMap();
}
public Service newService(String serviceName) {
if (!requestDefinitions.containsKey(serviceName)) {
Preconditions.checkState(!responseDefinitions.containsKey(serviceName));
addServiceDefinition(serviceName);
}
Service.Request request =
messageFactory.newProxy(serviceName, requestDefinitions.get(serviceName),
requestMessageClassRegistry.get(serviceName));
Service.Response response =
messageFactory.newProxy(serviceName, responseDefinitions.get(serviceName),
responseMessageClassRegistry.get(serviceName));
return new Service(request, response);
}
private void addServiceDefinition(String serviceName) {
String serviceDefinition = serviceLoader.getServiceDefinition(serviceName);
BufferedReader reader = new BufferedReader(new StringReader(serviceDefinition));
StringBuilder request = new StringBuilder();
StringBuilder response = new StringBuilder();
StringBuilder current = request;
String line;
try {
line = reader.readLine();
while (line != null) {
if (line.trim().equals("---")) {
Preconditions.checkState(current == request);
current = response;
} else {
current.append(line);
}
line = reader.readLine();
}
} catch (IOException e) {
throw new RosRuntimeException(e);
}
requestDefinitions.put(serviceName, request.toString());
responseDefinitions.put(serviceName, response.toString());
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.message.new_style;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Collection;
import java.util.Map;
import java.util.Queue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/**
* @author damonkohler@google.com (Damon Kohler)
*/
public class ServiceLoader {
private static final Log log = LogFactory.getLog(ServiceLoader.class);
private final Collection<File> searchPaths;
private final Map<String, String> serviceDefinitions;
public ServiceLoader() {
searchPaths = Sets.newHashSet();
serviceDefinitions = Maps.newConcurrentMap();
}
public void addSearchPath(File path) {
searchPaths.add(path);
}
public void updateServiceDefinitions() {
for (File searchPath : searchPaths) {
findMessages(searchPath);
}
}
private final class FindServicesFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() || pathname.getName().endsWith(".srv");
}
}
private String pathToServiceName(File root, File message) {
String absolutePath = message.getAbsolutePath();
String relativePath =
absolutePath.substring(root.getAbsolutePath().length() - root.getName().length());
String strippedExtension = relativePath.substring(0, relativePath.length() - 4);
return strippedExtension.replaceFirst("/srv/", "/");
}
private void findMessages(File searchPath) {
CharsetDecoder decoder = Charset.forName("US-ASCII").newDecoder();
FindServicesFilter filter = new FindServicesFilter();
Queue<File> childPaths = Lists.newLinkedList();
childPaths.addAll(listPathEntries(searchPath, filter));
while (!childPaths.isEmpty()) {
File servicePath = childPaths.poll();
if (servicePath.isDirectory()) {
childPaths.addAll(listPathEntries(servicePath, filter));
} else {
try {
addServiceDefinitionFromPaths(searchPath, servicePath, decoder);
} catch (IOException e) {
log.error("Failed to read service: " + servicePath.getAbsolutePath(), e);
}
}
}
}
private void addServiceDefinitionFromPaths(File searchPath, File servicePath,
CharsetDecoder decoder) throws IOException {
FileInputStream inputStream = new FileInputStream(servicePath);
FileChannel channel = inputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate((int) channel.size());
channel.read(buffer);
buffer.rewind();
decoder.reset();
String definition = decoder.decode(buffer).toString().trim();
serviceDefinitions.put(pathToServiceName(searchPath, servicePath), definition);
channel.close();
inputStream.close();
}
private Collection<File> listPathEntries(File searchPath, FindServicesFilter filter) {
File[] entries = searchPath.listFiles(filter);
if (entries == null) {
return Lists.newArrayList();
}
return Lists.newArrayList(entries);
}
public String getServiceDefinition(String serviceName) {
return serviceDefinitions.get(serviceName);
}
public boolean hasServiceDefinition(String serviceName) {
return serviceDefinitions.containsKey(serviceName);
}
@VisibleForTesting
ImmutableMap<String, String> getServiceDefinitions() {
return ImmutableMap.copyOf(serviceDefinitions);
}
@VisibleForTesting
void addServiceDefinition(String serviceName, String serviceDefinition) {
serviceDefinitions.put(serviceName, serviceDefinition);
}
}
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.ros.internal.message.old_style;
import org.ros.exception.RosRuntimeException;
import org.ros.message.Message;
import com.google.common.base.Preconditions;
/**
* A {@link org.ros.message.MessageFactory} for old style messages.
*
* @author damonkohler@google.com (Damon Kohler)
*/
public class MessageFactory implements org.ros.message.MessageFactory {
/**
* Java package prefix for root package for messages.
*/
private static final String ROS_MESSAGE_CLASS_PACKAGE_PREFIX = "org.ros.message";
/**
* Java package prefix for root package for services.
*/
private static final String ROS_SERVICE_CLASS_PACKAGE_PREFIX = "org.ros.service";
@SuppressWarnings("unchecked")
@Override
public <T> T newMessage(String messageType) {
try {
return (T) loadMessageClass(messageType, ROS_MESSAGE_CLASS_PACKAGE_PREFIX).newInstance();
} catch (Exception e) {
throw new RosRuntimeException(e);
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T newServiceResponse(String serviceType) {
try {
return (T) loadMessageClass(serviceType + "$Response", ROS_SERVICE_CLASS_PACKAGE_PREFIX)
.newInstance();
} catch (Exception e) {
throw new RosRuntimeException(e);
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T newServiceRequest(String serviceType) {
try {
return (T) loadMessageClass(serviceType + "$Request", ROS_SERVICE_CLASS_PACKAGE_PREFIX)
.newInstance();
} catch (Exception e) {
throw new RosRuntimeException(e);
}
}
/**
* Get the class for a given message type.
*
* @param messageType
* the string giving "ros package"/"message name", e.g. std_msgs/Time
* @param packagePath
* path to the package which contain messages
* @return the message class
* @throws RosRuntimeException
* no class representing that name or the class is not accessible
*/
@SuppressWarnings("unchecked")
private static Class<Message> loadMessageClass(String messageType, String packagePath) {
Preconditions.checkArgument(messageType.split("/").length == 2);
try {
return (Class<Message>) MessageFactory.class.getClassLoader().loadClass(
packagePath + "." + messageType.replace('/', '.'));
} catch (Exception e) {
throw new RosRuntimeException("Failed to load message type: \"" + messageType + "\"", e);
}
}
}
......@@ -18,18 +18,14 @@ package org.ros.internal.node;
import com.google.common.annotations.VisibleForTesting;
import org.ros.node.DefaultNodeFactory;
import org.apache.commons.logging.Log;
import org.ros.concurrent.CancellableLoop;
import org.ros.concurrent.ListenerCollection;
import org.ros.concurrent.ListenerCollection.SignalRunnable;
import org.ros.exception.RemoteException;
import org.ros.exception.ServiceNotFoundException;
import org.ros.internal.message.new_style.ServiceMessageDefinition;
import org.ros.internal.message.old_style.MessageDeserializer;
import org.ros.internal.message.old_style.MessageSerializer;
import org.ros.internal.message.old_style.ServiceMessageDefinitionFactory;
import org.ros.internal.message.service.ServiceDescription;
import org.ros.internal.message.topic.TopicDescription;
import org.ros.internal.node.client.MasterClient;
import org.ros.internal.node.client.Registrar;
import org.ros.internal.node.parameter.ParameterManager;
......@@ -37,23 +33,25 @@ import org.ros.internal.node.response.Response;
import org.ros.internal.node.response.StatusCode;
import org.ros.internal.node.server.NodeIdentifier;
import org.ros.internal.node.server.SlaveServer;
import org.ros.internal.node.service.ServiceDefinition;
import org.ros.internal.node.service.ServiceDeclaration;
import org.ros.internal.node.service.ServiceFactory;
import org.ros.internal.node.service.ServiceIdentifier;
import org.ros.internal.node.service.ServiceManager;
import org.ros.internal.node.service.ServiceResponseBuilder;
import org.ros.internal.node.topic.PublisherFactory;
import org.ros.internal.node.topic.SubscriberFactory;
import org.ros.internal.node.topic.TopicDefinition;
import org.ros.internal.node.topic.TopicManager;
import org.ros.internal.node.topic.TopicDeclaration;
import org.ros.internal.node.topic.TopicParticipantManager;
import org.ros.internal.node.xmlrpc.XmlRpcTimeoutException;
import org.ros.message.MessageDefinition;
import org.ros.message.MessageDeserializer;
import org.ros.message.MessageFactory;
import org.ros.message.MessageSerializationFactory;
import org.ros.message.MessageSerializer;
import org.ros.message.Time;
import org.ros.namespace.GraphName;
import org.ros.namespace.NameResolver;
import org.ros.namespace.NodeNameResolver;
import org.ros.node.DefaultNodeFactory;
import org.ros.node.Node;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeListener;
......@@ -95,7 +93,7 @@ public class DefaultNode implements Node {
private final RosoutLogger log;
private final MasterClient masterClient;
private final SlaveServer slaveServer;
private final TopicManager topicManager;
private final TopicParticipantManager topicParticipantManager;
private final ServiceManager serviceManager;
private final ParameterManager parameterManager;
private final PublisherFactory publisherFactory;
......@@ -121,19 +119,18 @@ public class DefaultNode implements Node {
* @param nodeConfiguration
* the {@link NodeConfiguration} for this {@link Node}
* @param nodeListeners
* a {@link Collection} of {@link NodeListener}s that will be
* added to this {@link Node} before it starts
* a {@link Collection} of {@link NodeListener}s that will be added
* to this {@link Node} before it starts
*/
public DefaultNode(NodeConfiguration nodeConfiguration,
Collection<NodeListener> nodeListeners,
public DefaultNode(NodeConfiguration nodeConfiguration, Collection<NodeListener> nodeListeners,
ScheduledExecutorService scheduledExecutorService) {
this.nodeConfiguration = NodeConfiguration.copyOf(nodeConfiguration);
this.nodeListeners = new ListenerCollection<NodeListener>(
nodeListeners, scheduledExecutorService);
this.nodeListeners =
new ListenerCollection<NodeListener>(nodeListeners, scheduledExecutorService);
this.scheduledExecutorService = scheduledExecutorService;
masterUri = nodeConfiguration.getMasterUri();
masterClient = new MasterClient(masterUri);
topicManager = new TopicManager();
topicParticipantManager = new TopicParticipantManager();
serviceManager = new ServiceManager();
parameterManager = new ParameterManager();
......@@ -141,25 +138,25 @@ public class DefaultNode implements Node {
NameResolver parentResolver = nodeConfiguration.getParentResolver();
nodeName = parentResolver.getNamespace().join(basename);
resolver = new NodeNameResolver(nodeName, parentResolver);
slaveServer = new SlaveServer(nodeName,
nodeConfiguration.getTcpRosBindAddress(),
slaveServer =
new SlaveServer(nodeName, nodeConfiguration.getTcpRosBindAddress(),
nodeConfiguration.getTcpRosAdvertiseAddress(),
nodeConfiguration.getXmlRpcBindAddress(),
nodeConfiguration.getXmlRpcAdvertiseAddress(), masterClient,
topicManager, serviceManager, parameterManager,
scheduledExecutorService);
nodeConfiguration.getXmlRpcAdvertiseAddress(), masterClient, topicParticipantManager,
serviceManager, parameterManager, scheduledExecutorService);
slaveServer.start();
NodeIdentifier nodeIdentifier = slaveServer.toSlaveIdentifier();
publisherFactory = new PublisherFactory(nodeIdentifier, topicManager,
nodeConfiguration.getMessageFactory(), scheduledExecutorService);
subscriberFactory = new SubscriberFactory(nodeIdentifier, topicManager,
scheduledExecutorService);
serviceFactory = new ServiceFactory(nodeName, slaveServer,
serviceManager, scheduledExecutorService);
NodeIdentifier nodeIdentifier = slaveServer.toNodeIdentifier();
publisherFactory =
new PublisherFactory(nodeIdentifier, topicParticipantManager,
nodeConfiguration.getTopicMessageFactory(), scheduledExecutorService);
subscriberFactory =
new SubscriberFactory(nodeIdentifier, topicParticipantManager, scheduledExecutorService);
serviceFactory =
new ServiceFactory(nodeName, slaveServer, serviceManager, scheduledExecutorService);
registrar = new Registrar(masterClient, scheduledExecutorService);
topicManager.setListener(registrar);
topicParticipantManager.setListener(registrar);
serviceManager.setListener(registrar);
registrar.start(nodeIdentifier);
......@@ -175,60 +172,49 @@ public class DefaultNode implements Node {
return registrar;
}
private <T> org.ros.message.MessageSerializer<T> newMessageSerializer(
String messageType) {
return nodeConfiguration.getMessageSerializationFactory()
.newMessageSerializer(messageType);
private <T> org.ros.message.MessageSerializer<T> newMessageSerializer(String messageType) {
return nodeConfiguration.getMessageSerializationFactory().newMessageSerializer(messageType);
}
@SuppressWarnings("unchecked")
private <T> MessageDeserializer<T> newMessageDeserializer(String messageType) {
return (MessageDeserializer<T>) nodeConfiguration
.getMessageSerializationFactory().newMessageDeserializer(
messageType);
return (MessageDeserializer<T>) nodeConfiguration.getMessageSerializationFactory()
.newMessageDeserializer(messageType);
}
@SuppressWarnings("unchecked")
private <T> MessageSerializer<T> newServiceResponseSerializer(
String serviceType) {
return (MessageSerializer<T>) nodeConfiguration
.getMessageSerializationFactory().newServiceResponseSerializer(
serviceType);
private <T> MessageSerializer<T> newServiceResponseSerializer(String serviceType) {
return (MessageSerializer<T>) nodeConfiguration.getMessageSerializationFactory()
.newServiceResponseSerializer(serviceType);
}
@SuppressWarnings("unchecked")
private <T> MessageDeserializer<T> newServiceResponseDeserializer(
String serviceType) {
return (MessageDeserializer<T>) nodeConfiguration
.getMessageSerializationFactory()
private <T> MessageDeserializer<T> newServiceResponseDeserializer(String serviceType) {
return (MessageDeserializer<T>) nodeConfiguration.getMessageSerializationFactory()
.newServiceResponseDeserializer(serviceType);
}
@SuppressWarnings("unchecked")
private <T> MessageSerializer<T> newServiceRequestSerializer(
String serviceType) {
return (MessageSerializer<T>) nodeConfiguration
.getMessageSerializationFactory().newServiceRequestSerializer(
serviceType);
private <T> MessageSerializer<T> newServiceRequestSerializer(String serviceType) {
return (MessageSerializer<T>) nodeConfiguration.getMessageSerializationFactory()
.newServiceRequestSerializer(serviceType);
}
@SuppressWarnings("unchecked")
private <T> MessageDeserializer<T> newServiceRequestDeserializer(
String serviceType) {
return (MessageDeserializer<T>) nodeConfiguration
.getMessageSerializationFactory()
private <T> MessageDeserializer<T> newServiceRequestDeserializer(String serviceType) {
return (MessageDeserializer<T>) nodeConfiguration.getMessageSerializationFactory()
.newServiceRequestDeserializer(serviceType);
}
@Override
public <T> Publisher<T> newPublisher(GraphName topicName, String messageType) {
GraphName resolvedTopicName = resolveName(topicName);
MessageDefinition messageDefinition = nodeConfiguration
.getMessageDefinitionFactory().newFromMessageType(messageType);
TopicDefinition topicDefinition = TopicDefinition.newFromTopicName(
resolvedTopicName, messageDefinition);
TopicDescription topicDescription =
nodeConfiguration.getTopicDescriptionFactory().newFromType(messageType);
TopicDeclaration topicDeclaration =
TopicDeclaration.newFromTopicName(resolvedTopicName, topicDescription);
org.ros.message.MessageSerializer<T> serializer = newMessageSerializer(messageType);
return publisherFactory.newOrExisting(topicDefinition, serializer);
return publisherFactory.newOrExisting(topicDeclaration, serializer);
}
@Override
......@@ -237,16 +223,14 @@ public class DefaultNode implements Node {
}
@Override
public <T> Subscriber<T> newSubscriber(GraphName topicName,
String messageType) {
public <T> Subscriber<T> newSubscriber(GraphName topicName, String messageType) {
GraphName resolvedTopicName = resolveName(topicName);
MessageDefinition messageDefinition = nodeConfiguration
.getMessageDefinitionFactory().newFromMessageType(messageType);
TopicDefinition topicDefinition = TopicDefinition.newFromTopicName(
resolvedTopicName, messageDefinition);
TopicDescription topicDescription =
nodeConfiguration.getTopicDescriptionFactory().newFromType(messageType);
TopicDeclaration topicDeclaration =
TopicDeclaration.newFromTopicName(resolvedTopicName, topicDescription);
MessageDeserializer<T> deserializer = newMessageDeserializer(messageType);
Subscriber<T> subscriber = subscriberFactory.newOrExisting(
topicDefinition, deserializer);
Subscriber<T> subscriber = subscriberFactory.newOrExisting(topicDeclaration, deserializer);
return subscriber;
}
......@@ -256,63 +240,56 @@ public class DefaultNode implements Node {
}
@Override
public <T, S> ServiceServer<T, S> newServiceServer(GraphName serviceName,
String serviceType, ServiceResponseBuilder<T, S> responseBuilder) {
public <T, S> ServiceServer<T, S> newServiceServer(GraphName serviceName, String serviceType,
ServiceResponseBuilder<T, S> responseBuilder) {
GraphName resolvedServiceName = resolveName(serviceName);
// TODO(damonkohler): It's rather non-obvious that the URI will be
// created
// later on the fly.
ServiceIdentifier identifier = new ServiceIdentifier(
resolvedServiceName, null);
ServiceMessageDefinition messageDefinition = ServiceMessageDefinitionFactory
.newFromString(serviceType);
ServiceDefinition definition = new ServiceDefinition(identifier,
messageDefinition);
// created later on the fly.
ServiceIdentifier identifier = new ServiceIdentifier(resolvedServiceName, null);
ServiceDescription serviceDescription =
nodeConfiguration.getServiceDescriptionFactory().newFromType(serviceType);
ServiceDeclaration definition = new ServiceDeclaration(identifier, serviceDescription);
MessageDeserializer<T> requestDeserializer = newServiceRequestDeserializer(serviceType);
MessageSerializer<S> responseSerializer = newServiceResponseSerializer(serviceType);
return serviceFactory.newServer(definition, requestDeserializer,
responseSerializer, responseBuilder);
return serviceFactory.newServer(definition, requestDeserializer, responseSerializer,
responseBuilder);
}
@Override
public <T, S> ServiceServer<T, S> newServiceServer(String serviceName,
String serviceType, ServiceResponseBuilder<T, S> responseBuilder) {
return newServiceServer(new GraphName(serviceName), serviceType,
responseBuilder);
public <T, S> ServiceServer<T, S> newServiceServer(String serviceName, String serviceType,
ServiceResponseBuilder<T, S> responseBuilder) {
return newServiceServer(new GraphName(serviceName), serviceType, responseBuilder);
}
@Override
public <T, S> ServiceClient<T, S> newServiceClient(GraphName serviceName,
String serviceType) throws ServiceNotFoundException {
public <T, S> ServiceClient<T, S> newServiceClient(GraphName serviceName, String serviceType)
throws ServiceNotFoundException {
GraphName resolvedServiceName = resolveName(serviceName);
URI uri = lookupService(resolvedServiceName);
if (uri == null) {
throw new ServiceNotFoundException("No such service "
+ resolvedServiceName + " of type " + serviceType);
}
ServiceMessageDefinition messageDefinition = ServiceMessageDefinitionFactory
.newFromString(serviceType);
ServiceIdentifier serviceIdentifier = new ServiceIdentifier(
resolvedServiceName, uri);
ServiceDefinition definition = new ServiceDefinition(serviceIdentifier,
messageDefinition);
throw new ServiceNotFoundException("No such service " + resolvedServiceName + " of type "
+ serviceType);
}
ServiceDescription serviceDescription =
nodeConfiguration.getServiceDescriptionFactory().newFromType(serviceType);
ServiceIdentifier serviceIdentifier = new ServiceIdentifier(resolvedServiceName, uri);
ServiceDeclaration definition = new ServiceDeclaration(serviceIdentifier, serviceDescription);
MessageSerializer<T> requestSerializer = newServiceRequestSerializer(serviceType);
MessageDeserializer<S> responseDeserializer = newServiceResponseDeserializer(serviceType);
return serviceFactory.newClient(definition, requestSerializer,
responseDeserializer);
return serviceFactory.newClient(definition, requestSerializer, responseDeserializer);
}
@Override
public <T, S> ServiceClient<T, S> newServiceClient(String serviceName,
String serviceType) throws ServiceNotFoundException {
public <T, S> ServiceClient<T, S> newServiceClient(String serviceName, String serviceType)
throws ServiceNotFoundException {
return newServiceClient(new GraphName(serviceName), serviceType);
}
@Override
public URI lookupService(GraphName serviceName) {
Response<URI> response = masterClient.lookupService(slaveServer
.toSlaveIdentifier().getNodeName(), resolveName(serviceName)
.toString());
Response<URI> response =
masterClient.lookupService(slaveServer.toNodeIdentifier().getNodeName(),
resolveName(serviceName).toString());
if (response.getStatusCode() == StatusCode.SUCCESS) {
return response.getResult();
} else {
......@@ -361,20 +338,19 @@ public class DefaultNode implements Node {
// NOTE(damonkohler): We don't want to raise potentially spurious
// exceptions during shutdown that would interrupt the process. This is
// simply best effort cleanup.
for (Publisher<?> publisher : topicManager.getPublishers()) {
for (Publisher<?> publisher : topicParticipantManager.getPublishers()) {
publisher.shutdown();
}
for (Subscriber<?> subscriber : topicManager.getSubscribers()) {
for (Subscriber<?> subscriber : topicParticipantManager.getSubscribers()) {
subscriber.shutdown();
}
for (ServiceServer<?, ?> serviceServer : serviceManager.getServers()) {
try {
Response<Integer> response = masterClient.unregisterService(
slaveServer.toSlaveIdentifier(), serviceServer);
Response<Integer> response =
masterClient.unregisterService(slaveServer.toNodeIdentifier(), serviceServer);
if (DEBUG) {
if (response.getResult() == 0) {
System.err.println("Failed to unregister service: "
+ serviceServer.getName());
System.err.println("Failed to unregister service: " + serviceServer.getName());
}
}
} catch (XmlRpcTimeoutException e) {
......@@ -403,9 +379,8 @@ public class DefaultNode implements Node {
@Override
public ParameterTree newParameterTree() {
return org.ros.internal.node.parameter.DefaultParameterTree
.newFromSlaveIdentifier(slaveServer.toSlaveIdentifier(),
masterClient.getRemoteUri(), resolver, parameterManager);
return org.ros.internal.node.parameter.DefaultParameterTree.newFromSlaveIdentifier(
slaveServer.toNodeIdentifier(), masterClient.getRemoteUri(), resolver, parameterManager);
}
@Override
......@@ -419,8 +394,18 @@ public class DefaultNode implements Node {
}
@Override
public MessageFactory getMessageFactory() {
return nodeConfiguration.getMessageFactory();
public MessageFactory getTopicMessageFactory() {
return nodeConfiguration.getTopicMessageFactory();
}
@Override
public MessageFactory getServiceRequestMessageFactory() {
return nodeConfiguration.getServiceRequestMessageFactory();
}
@Override
public MessageFactory getServiceResponseMessageFactory() {
return nodeConfiguration.getServiceResponseMessageFactory();
}
@Override
......@@ -434,8 +419,7 @@ public class DefaultNode implements Node {
}
/**
* SignalRunnable all {@link NodeListener}s that the {@link Node} has
* started.
* SignalRunnable all {@link NodeListener}s that the {@link Node} has started.
*
* <p>
* Each listener is called in a separate thread.
......@@ -451,8 +435,8 @@ public class DefaultNode implements Node {
}
/**
* SignalRunnable all {@link NodeListener}s that the {@link Node} has
* started shutting down.
* SignalRunnable all {@link NodeListener}s that the {@link Node} has started
* shutting down.
*
* <p>
* Each listener is called in a separate thread.
......
......@@ -16,16 +16,16 @@
package org.ros.internal.node;
import java.io.PrintWriter;
import java.io.StringWriter;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ros.node.Node;
import org.ros.node.topic.Publisher;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
/**
* Logger that logs to both an underlying Apache Commons Log as well as /rosout.
......@@ -37,7 +37,7 @@ public class RosoutLogger implements Log {
private static final String ROSOUT_TOPIC = "/rosout";
private final Node node;
private final Publisher<org.ros.message.rosgraph_msgs.Log> publisher;
private final Publisher<rosgraph_msgs.Log> publisher;
private final Log log;
RosoutLogger(Node node) {
......@@ -47,7 +47,7 @@ public class RosoutLogger implements Log {
}
@VisibleForTesting
Publisher<org.ros.message.rosgraph_msgs.Log> getPublisher() {
Publisher<rosgraph_msgs.Log> getPublisher() {
return publisher;
}
......@@ -59,16 +59,17 @@ public class RosoutLogger implements Log {
}
private void publish(byte level, Object message) {
org.ros.message.rosgraph_msgs.Log m = new org.ros.message.rosgraph_msgs.Log();
m.header.stamp = node.getCurrentTime();
m.level = level;
m.name = node.getName().toString();
m.msg = message.toString();
rosgraph_msgs.Log logMessage =
node.getTopicMessageFactory().newFromType(rosgraph_msgs.Log._TYPE);
logMessage.getMessage("header").setTime("stamp", node.getCurrentTime());
logMessage.level(level);
logMessage.name(node.getName().toString());
logMessage.msg(message.toString());
// TODO(damonkohler): Should return list of all published and subscribed
// topics for the node that created this logger. This helps filter the
// rosoutconsole.
m.topics = Lists.newArrayList();
publisher.publish(m);
logMessage.topics(new ArrayList<String>());
publisher.publish(logMessage);
}
@Override
......@@ -105,7 +106,7 @@ public class RosoutLogger implements Log {
public void trace(Object message) {
log.trace(message);
if (log.isTraceEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.DEBUG, message);
publish(rosgraph_msgs.Log.DEBUG, message);
}
}
......@@ -113,7 +114,7 @@ public class RosoutLogger implements Log {
public void trace(Object message, Throwable t) {
log.trace(message, t);
if (log.isTraceEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.DEBUG, message, t);
publish(rosgraph_msgs.Log.DEBUG, message, t);
}
}
......@@ -121,7 +122,7 @@ public class RosoutLogger implements Log {
public void debug(Object message) {
log.debug(message);
if (log.isDebugEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.DEBUG, message);
publish(rosgraph_msgs.Log.DEBUG, message);
}
}
......@@ -129,7 +130,7 @@ public class RosoutLogger implements Log {
public void debug(Object message, Throwable t) {
log.debug(message, t);
if (log.isDebugEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.DEBUG, message, t);
publish(rosgraph_msgs.Log.DEBUG, message, t);
}
}
......@@ -137,7 +138,7 @@ public class RosoutLogger implements Log {
public void info(Object message) {
log.info(message);
if (log.isInfoEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.INFO, message);
publish(rosgraph_msgs.Log.INFO, message);
}
}
......@@ -145,7 +146,7 @@ public class RosoutLogger implements Log {
public void info(Object message, Throwable t) {
log.info(message, t);
if (log.isInfoEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.INFO, message, t);
publish(rosgraph_msgs.Log.INFO, message, t);
}
}
......@@ -153,7 +154,7 @@ public class RosoutLogger implements Log {
public void warn(Object message) {
log.warn(message);
if (log.isWarnEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.WARN, message);
publish(rosgraph_msgs.Log.WARN, message);
}
}
......@@ -161,7 +162,7 @@ public class RosoutLogger implements Log {
public void warn(Object message, Throwable t) {
log.warn(message, t);
if (log.isWarnEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.WARN, message, t);
publish(rosgraph_msgs.Log.WARN, message, t);
}
}
......@@ -169,7 +170,7 @@ public class RosoutLogger implements Log {
public void error(Object message) {
log.error(message);
if (log.isErrorEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.ERROR, message);
publish(rosgraph_msgs.Log.ERROR, message);
}
}
......@@ -177,7 +178,7 @@ public class RosoutLogger implements Log {
public void error(Object message, Throwable t) {
log.error(message, t);
if (log.isErrorEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.ERROR, message, t);
publish(rosgraph_msgs.Log.ERROR, message, t);
}
}
......@@ -185,7 +186,7 @@ public class RosoutLogger implements Log {
public void fatal(Object message) {
log.fatal(message);
if (log.isFatalEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.FATAL, message);
publish(rosgraph_msgs.Log.FATAL, message);
}
}
......@@ -193,7 +194,7 @@ public class RosoutLogger implements Log {
public void fatal(Object message, Throwable t) {
log.fatal(message, t);
if (log.isFatalEnabled() && publisher != null) {
publish(org.ros.message.rosgraph_msgs.Log.FATAL, message, t);
publish(rosgraph_msgs.Log.FATAL, message, t);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment