Author: chathura
Date: Wed Jan 16 08:57:44 2008
New Revision: 12358
Log:
Refactored QueryProcessor insterface. Now it can support general query
implementations with name->value pairs as parameters.
Added:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessorManager.java
- copied, changed from r12300,
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessorFactory.java
trunk/registry/modules/webapps/src/main/java/org/wso2/registry/web/utils/SigninUtil.java
Removed:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessorFactory.java
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/Registry.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/AtomRegistry.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/RemoteRegistry.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/inmemory/InMemoryRegistry.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessor.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/SQLQueryProcessor.java
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/JDBCRegistryTest.java
trunk/registry/modules/core/src/test/java/org/wso2/registry/secure/SecureRegistryTest.java
trunk/registry/modules/webapps/src/main/java/org/wso2/registry/web/actions/utils/AdvancedResourceQuery.java
trunk/registry/modules/webapps/src/main/webapp/admin/header.jsp
trunk/registry/modules/webapps/src/main/webapp/admin/js/common.js
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/Registry.java
==============================================================================
--- trunk/registry/modules/core/src/main/java/org/wso2/registry/Registry.java
(original)
+++ trunk/registry/modules/core/src/main/java/org/wso2/registry/Registry.java
Wed Jan 16 08:57:44 2008
@@ -20,6 +20,7 @@
package org.wso2.registry;
import java.util.Date;
+import java.util.Map;
/** API for the Registry. Java applications should use this API to access the
registry. */
public interface Registry {
@@ -216,7 +217,7 @@
* @return RowSet containing the fields specified in the query.
* @throws RegistryException depends on the implementation.
*/
- Resource executeQuery(String path, Object[] parameters) throws
RegistryException;
+ Resource executeQuery(String path, Map parameters) throws
RegistryException;
/**
* Returns the logs of the activities occured in the registy.
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/AtomRegistry.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/AtomRegistry.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/AtomRegistry.java
Wed Jan 16 08:57:44 2008
@@ -21,6 +21,7 @@
import org.apache.abdera.Abdera;
import org.apache.abdera.factory.Factory;
import org.apache.abdera.model.*;
+import org.apache.abdera.model.Collection;
import org.apache.abdera.parser.Parser;
import org.apache.abdera.protocol.server.Provider;
import org.apache.abdera.protocol.server.RequestContext;
@@ -44,10 +45,7 @@
import javax.activation.MimeType;
import javax.xml.namespace.QName;
import java.io.ByteArrayInputStream;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
+import java.util.*;
public class AtomRegistry extends AbstractProvider implements Provider {
@@ -336,7 +334,7 @@
try {
// Trying to execute a query for a given path for a given
paramater
String parms = request.getHeader("parameters");
- String[] parameters =
+ Map parameters =
RemoteRegistry.decodeParametesAsString(parms);
resource =
getSecureRegistry(request).executeQuery(resourcePath, parameters);
feed = populateFeed(abdera, baseURI, resourcePath,
resource, true);
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/RemoteRegistry.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/RemoteRegistry.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/app/RemoteRegistry.java
Wed Jan 16 08:57:44 2008
@@ -34,10 +34,7 @@
import javax.xml.namespace.QName;
import java.io.*;
import java.net.URL;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
+import java.util.*;
public class RemoteRegistry implements Registry, RegistryConstants {
@@ -483,7 +480,7 @@
return Integer.parseInt(intvalue);
}
- public Resource executeQuery(String path, Object[] parameters) throws
RegistryException {
+ public Resource executeQuery(String path, Map parameters) throws
RegistryException {
Abdera abdera = new Abdera();
AbderaClient abderaClient = new AbderaClient(abdera);
RequestOptions requestOptions = getAuthorization();
@@ -497,21 +494,46 @@
return createResourceFromFeed(feed, true);
}
- public static String encodeParametersAsString(Object[] parameters) {
+ public static String encodeParametersAsString(Map parameters) {
String value = "";
- for (int i = 0; i < parameters.length; i++) {
- Object parameter = parameters[i];
- if (i < parameters.length - 1) {
- value = value + parameter + "#";
+ Iterator iParams = parameters.keySet().iterator();
+ while (iParams.hasNext()) {
+ String paramNumber = (String) iParams.next();
+ String paramValue = (String) parameters.get(paramNumber);
+
+ if (iParams.hasNext()) {
+ value = value + paramNumber + ":" + paramValue + "#";
} else {
- value = value + parameter;
+ value = value + paramNumber + ":" + paramValue;
}
}
+
+ //for (int i = 0; i < parameters.length; i++) {
+ // Object parameter = parameters[i];
+ // if (i < parameters.length - 1) {
+ // value = value + parameter + "#";
+ // } else {
+ // value = value + parameter;
+ // }
+ //}
return value;
}
- public static String[] decodeParametesAsString(String value) {
- return value.split("\\#");
+ public static Map decodeParametesAsString(String value) {
+
+ Map paramMap = new HashMap();
+
+ String[] params = value.trim().split("#");
+ for (int i = 0; i < params.length; i++) {
+ if (params[i].trim().length() == 0) {
+ continue;
+ }
+
+ String[] paramParts = params[i].trim().split(":");
+ paramMap.put(paramParts[0], paramParts[1]);
+ }
+
+ return paramMap;
}
public LogEntry[] getLogs(String resourcePath,
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/inmemory/InMemoryRegistry.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/inmemory/InMemoryRegistry.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/inmemory/InMemoryRegistry.java
Wed Jan 16 08:57:44 2008
@@ -249,7 +249,7 @@
"User
level rating"));
}
- public Resource executeQuery(String path, Object[] parameters) throws
RegistryException {
+ public Resource executeQuery(String path, Map parameters) throws
RegistryException {
throw new
UnsupportedOperationException(Messages.getMessage("unsupported.exception",
"Custom
queries"));
}
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/JDBCRegistry.java
Wed Jan 16 08:57:44 2008
@@ -27,7 +27,7 @@
import org.wso2.registry.jdbc.dao.*;
import org.wso2.registry.jdbc.mediatypes.MediaTypeManager;
import org.wso2.registry.jdbc.queries.QueryProcessor;
-import org.wso2.registry.jdbc.queries.QueryProcessorFactory;
+import org.wso2.registry.jdbc.queries.QueryProcessorManager;
import org.wso2.registry.jdbc.realm.RegistryRealm;
import org.wso2.registry.jdbc.urlhandlers.URLHandlerManager;
import org.wso2.registry.utils.AuthorizationUtil;
@@ -36,10 +36,7 @@
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
/**
* JDBC based implementation of the Registry. This will be used mostly as the
back-end by other
@@ -55,6 +52,7 @@
private DataSource dataSource = null;
private URLHandlerManager urlHandlerManager;
private MediaTypeManager mediaTypeManager;
+ private QueryProcessorManager queryProcessorManager;
private VersionedResourceDAO resourceDAO = null;
private TagsDAO tagsDAO = null;
private CommentsDAO commentsDAO = null;
@@ -119,6 +117,7 @@
urlHandlerManager = new URLHandlerManager(dataSource);
mediaTypeManager = new MediaTypeManager(dataSource, realm);
+ queryProcessorManager = new QueryProcessorManager(dataSource);
resourceDAO = new VersionedResourceDAO();
tagsDAO = new TagsDAO();
@@ -972,18 +971,18 @@
}
- public Resource executeQuery(String path, Object[] parameters) throws
RegistryException {
+ public Resource executeQuery(String path, Map parameters) throws
RegistryException {
Connection conn = getConnection();
try {
Resource query = get(path);
- QueryProcessor queryProcessor =
- new
QueryProcessorFactory().getQueryProcessor(query.getMediaType());
- if (queryProcessor == null) {
- throw new RegistryException("Undefined query type: " +
query.getMediaType());
- }
- return queryProcessor.executeQuery(query, parameters, conn);
+ //QueryProcessor queryProcessor =
+ // new
QueryProcessorManager().getQueryProcessor(query.getMediaType());
+ //if (queryProcessor == null) {
+ // throw new RegistryException("Undefined query type: " +
query.getMediaType());
+ //}
+ return queryProcessorManager.executeQuery(query, parameters);
} finally {
try {
conn.close();
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessor.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessor.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessor.java
Wed Jan 16 08:57:44 2008
@@ -19,10 +19,18 @@
import org.wso2.registry.RegistryException;
import org.wso2.registry.Resource;
+import javax.sql.DataSource;
import java.sql.Connection;
+import java.util.Map;
-public interface QueryProcessor {
+public abstract class QueryProcessor {
- public Resource executeQuery(Resource query, Object[] parameters,
Connection conn)
+ protected DataSource dataSource;
+
+ public QueryProcessor(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ public abstract Resource executeQuery(Resource query, Map parameters)
throws RegistryException;
}
Copied:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessorManager.java
(from r12300,
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessorFactory.java)
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessorFactory.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/QueryProcessorManager.java
Wed Jan 16 08:57:44 2008
@@ -17,19 +17,47 @@
package org.wso2.registry.jdbc.queries;
import org.wso2.registry.RegistryConstants;
+import org.wso2.registry.Resource;
+import org.wso2.registry.RegistryException;
+import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
-public class QueryProcessorFactory {
+public class QueryProcessorManager {
+ private DataSource dataSource;
private Map queryProcessors = new HashMap();
- public QueryProcessorFactory() {
- queryProcessors.put(RegistryConstants.SQL_QUERY_MEDIA_TYPE, new
SQLQueryProcessor());
+ public QueryProcessorManager(DataSource dataSource) {
+
+ this.dataSource = dataSource;
+
+ queryProcessors.
+ put(RegistryConstants.SQL_QUERY_MEDIA_TYPE, new
SQLQueryProcessor(dataSource));
}
public QueryProcessor getQueryProcessor(String queryType) {
return (QueryProcessor)queryProcessors.get(queryType);
}
+
+ public Resource executeQuery(Resource queryResource, Map parameters)
throws RegistryException {
+
+ if (queryResource.getMediaType() == null ||
queryResource.getMediaType().length() == 0) {
+ String msg = "Failed to execute query at path: " +
queryResource.getPath() +
+ ". Query resources should have a media type to map to a
query processor.";
+ throw new RegistryException(msg);
+ }
+
+ QueryProcessor queryProcessor =
+ (QueryProcessor)
queryProcessors.get(queryResource.getMediaType());
+ if (queryProcessor == null) {
+ String msg = "Failed to execute query at path: " +
queryResource.getPath() +
+ ". No query processor is associated with the query type: "
+
+ queryResource.getMediaType();
+ throw new RegistryException(msg);
+ }
+
+ return queryProcessor.executeQuery(queryResource, parameters);
+ }
}
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/SQLQueryProcessor.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/SQLQueryProcessor.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/jdbc/queries/SQLQueryProcessor.java
Wed Jan 16 08:57:44 2008
@@ -27,30 +27,46 @@
import org.wso2.registry.jdbc.dataobjects.RatingDO;
import org.wso2.registry.jdbc.dataobjects.TaggingDO;
+import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Iterator;
-public class SQLQueryProcessor implements QueryProcessor {
+public class SQLQueryProcessor extends QueryProcessor {
private static final Log log = LogFactory.getLog(SQLQueryProcessor.class);
- public Resource executeQuery(Resource query, Object[] parameters,
Connection conn)
+ public SQLQueryProcessor(DataSource dataSource) {
+ super(dataSource);
+ }
+
+ public Resource executeQuery(Resource query, Map parameters)
throws RegistryException {
try {
String sqlString = (String)query.getContent();
+ Connection conn = dataSource.getConnection();
PreparedStatement s = conn.prepareStatement(sqlString);
if (parameters != null) {
- for (int i = 0; i < parameters.length; i++) {
- s.setObject(i + 1, parameters[i]);
+
+ Iterator iParams = parameters.keySet().iterator();
+ while (iParams.hasNext()) {
+ String paramNumber = (String) iParams.next();
+ Object paramValue = parameters.get(paramNumber);
+ s.setObject(Integer.parseInt(paramNumber), paramValue);
}
+
+ //for (int i = 0; i < parameters.length; i++) {
+ // s.setObject(i + 1, parameters[i]);
+ //}
}
ResultSet results = s.executeQuery();
Modified:
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
==============================================================================
---
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
(original)
+++
trunk/registry/modules/core/src/main/java/org/wso2/registry/secure/SecureRegistry.java
Wed Jan 16 08:57:44 2008
@@ -33,6 +33,7 @@
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
+import java.util.Map;
/**
* Registry implementation to perform authentication and authorization. Each
user should use a
@@ -591,7 +592,7 @@
return registry.getRating(resourcePath, userName);
}
- public Resource executeQuery(String path, Object[] parameters) throws
RegistryException {
+ public Resource executeQuery(String path, Map parameters) throws
RegistryException {
User.setCurrentUser(userID);
return registry.executeQuery(path, parameters);
}
Modified:
trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/JDBCRegistryTest.java
==============================================================================
---
trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/JDBCRegistryTest.java
(original)
+++
trunk/registry/modules/core/src/test/java/org/wso2/registry/jdbc/JDBCRegistryTest.java
Wed Jan 16 08:57:44 2008
@@ -22,10 +22,7 @@
import junit.framework.TestCase;
import org.wso2.registry.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Properties;
+import java.util.*;
public class JDBCRegistryTest extends TestCase {
@@ -576,7 +573,9 @@
}
try {
- Resource result1 = registry.executeQuery("/qs/q1", new
String[]{"%production%"});
+ Map parameters = new HashMap();
+ parameters.put("1", "%production%");
+ Resource result1 = registry.executeQuery("/qs/q1", parameters);
assertTrue("Search with result type Resource should return a
directory.",
result1.isDirectory());
@@ -635,7 +634,9 @@
}
try {
- Resource result1 = registry.executeQuery("/qs/q2", new
String[]{"%production%"});
+ Map parameters = new HashMap();
+ parameters.put("1", "%production%");
+ Resource result1 = registry.executeQuery("/qs/q2", parameters);
assertTrue("Search with result type Resource should return a
directory.",
result1.isDirectory());
@@ -698,7 +699,9 @@
}
try {
- Resource result1 = registry.executeQuery("/qs/q3", new
String[]{"%production%"});
+ Map parameters = new HashMap();
+ parameters.put("1", "%production%");
+ Resource result1 = registry.executeQuery("/qs/q3", parameters);
assertTrue("Search with result type tags should return a
directory.",
result1.isDirectory());
@@ -761,7 +764,9 @@
}
try {
- Resource result1 = registry.executeQuery("/qs/q4", new
String[]{"%production%"});
+ Map parameters = new HashMap();
+ parameters.put("1", "%production%");
+ Resource result1 = registry.executeQuery("/qs/q4", parameters);
assertTrue("Search with result type Comment should return a
collection.",
result1.isDirectory());
Modified:
trunk/registry/modules/core/src/test/java/org/wso2/registry/secure/SecureRegistryTest.java
==============================================================================
---
trunk/registry/modules/core/src/test/java/org/wso2/registry/secure/SecureRegistryTest.java
(original)
+++
trunk/registry/modules/core/src/test/java/org/wso2/registry/secure/SecureRegistryTest.java
Wed Jan 16 08:57:44 2008
@@ -28,6 +28,7 @@
import org.wso2.usermanager.UserManagerException;
import java.io.*;
+import java.util.HashMap;
public class SecureRegistryTest extends TestCase {
@@ -340,7 +341,7 @@
//String sql = "SELECT A.AID FROM ARTIFACTS A, VERSIONS V, TAGS T,
COMMENTS C WHERE A.AID=V.AID AND V.VN IN (SELECT MAX(V2.VN) FROM VERSIONS V2
WHERE A.AID=V2.AID) AND A.AID=T.AID AND A.AID=C.AID AND A.PATH='c1200/r4'";
//String sql = "SELECT A.PATH FROM ARTIFACTS A WHERE
A.PATH='/c1200/r4'";
- Resource q1Results = registry.executeQuery("/advanced/q1", new
String[]{});
+ Resource q1Results = registry.executeQuery("/advanced/q1", new
HashMap());
int a = 1;
} catch (RegistryException e) {
Modified:
trunk/registry/modules/webapps/src/main/java/org/wso2/registry/web/actions/utils/AdvancedResourceQuery.java
==============================================================================
---
trunk/registry/modules/webapps/src/main/java/org/wso2/registry/web/actions/utils/AdvancedResourceQuery.java
(original)
+++
trunk/registry/modules/webapps/src/main/java/org/wso2/registry/web/actions/utils/AdvancedResourceQuery.java
Wed Jan 16 08:57:44 2008
@@ -23,9 +23,7 @@
import org.wso2.registry.secure.SecureRegistry;
import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
/**
* Represents an advanced query on normal resources. Handles all details of
defining, executing and
@@ -108,7 +106,13 @@
params.add(tag3);
}
- Resource resultCollection = registry.executeQuery(queryPath,
params.toArray());
+ Map paramMap = new HashMap();
+ for (int i = 0; i < params.size(); i++) {
+ Object value = params.get(i);
+ paramMap.put(new Integer(i + 1).toString(), value);
+ }
+
+ Resource resultCollection = registry.executeQuery(queryPath, paramMap);
return resultCollection;
}
Added:
trunk/registry/modules/webapps/src/main/java/org/wso2/registry/web/utils/SigninUtil.java
==============================================================================
--- (empty file)
+++
trunk/registry/modules/webapps/src/main/java/org/wso2/registry/web/utils/SigninUtil.java
Wed Jan 16 08:57:44 2008
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2006, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * 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.wso2.registry.web.utils;
+
+import javax.servlet.http.HttpServletRequest;
+
+public class SigninUtil {
+
+ //public static void signIn(HttpServletRequest)
+}
Modified: trunk/registry/modules/webapps/src/main/webapp/admin/header.jsp
==============================================================================
--- trunk/registry/modules/webapps/src/main/webapp/admin/header.jsp
(original)
+++ trunk/registry/modules/webapps/src/main/webapp/admin/header.jsp Wed Jan
16 08:57:44 2008
@@ -14,9 +14,9 @@
</table>
- <div class="popup-bot">
+ <div id="loginBox" class="popup-bot">
- <form action="/wso2registry/system/signin" method="post">
+ <form>
<table class="form-table" border="0" cellspacing="0"
cellpadding="0" style=" width:100%">
<tr>
<td>User Name:</td>
@@ -29,7 +29,7 @@
<tr>
<td></td>
<td>
- <input id="signin" type="submit" class="button"
value="Sign In"/> <input type="button" class="button" value="Cancel"
onclick="showHideCommon('popup-main'); showHideCommon('popup');"
style="margin-left:10px;" />
+ <input id="signin" type="button" class="button"
value="Sign In"/> <input type="button" class="button" value="Cancel"
onclick="showHideCommon('popup-main'); showHideCommon('popup');"
style="margin-left:10px;" />
</td>
</tr>
Modified: trunk/registry/modules/webapps/src/main/webapp/admin/js/common.js
==============================================================================
--- trunk/registry/modules/webapps/src/main/webapp/admin/js/common.js
(original)
+++ trunk/registry/modules/webapps/src/main/webapp/admin/js/common.js Wed Jan
16 08:57:44 2008
@@ -233,6 +233,16 @@
}
}
+function login() {
+ var userName = document.getElementById('userName').value;
+ var password = document.getElementById('password').value;
+
+ new Ajax.request()
+ new Ajax.Updater('loginBox', '/wso2registry/system/signin', { method:
'post', parameters: {userName: userName, password: password} });
+
+ document.refresh();
+}
+
/* Ajax Rating Functions */
function setRating(rating) {
_______________________________________________
Registry-dev mailing list
[email protected]
http://wso2.org/cgi-bin/mailman/listinfo/registry-dev