
org.glassfish.admin.rest.wadl.RestModelSchemaResource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rest-service Show documentation
Show all versions of rest-service Show documentation
Rest Interface for GlassFish Management and Monitoring
The newest version!
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation.
* Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.admin.rest.wadl;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.SchemaOutputResolver;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import javax.xml.transform.stream.StreamResult;
import org.glassfish.admin.rest.RestLogging;
import org.glassfish.admin.rest.composite.LegacyCompositeResource;
import org.glassfish.admin.rest.composite.RestModel;
import org.glassfish.hk2.api.ActiveDescriptor;
import org.glassfish.hk2.utilities.BuilderHelper;
import org.glassfish.internal.api.Globals;
import org.jvnet.hk2.annotations.Service;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
*
* @author jdlee
*/
@Path("/schema.xsd")
@Service
public class RestModelSchemaResource extends LegacyCompositeResource {
@GET
@Path("old")
public String getSchema() throws JAXBException, IOException {
Set> classes = new TreeSet<>(new Comparator>() {
@Override
public int compare(Class> t, Class> t1) {
return t.getName().compareTo(t1.getName());
}
});
for (String c : locateRestModels()) {
try {
Class> modelClass = loadClass(c);
if (modelClass.getSimpleName().charAt(0) < 'C') {
classes.add(getCompositeUtil().getModel(modelClass).getClass());
}
} catch (ClassNotFoundException ex) {
RestLogging.restLogger.log(Level.WARNING, null, ex);
}
}
JAXBContext jc = JAXBContext.newInstance(classes.toArray(Class[]::new));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
jc.generateSchema(new MySchemaOutputResolver(baos));
return new String(baos.toByteArray(), UTF_8);
}
@GET
@Path("test1")
public String getSchema1() throws JAXBException, IOException {
Set> classes = new TreeSet<>(new Comparator>() {
@Override
public int compare(Class> t, Class> t1) {
return t.getName().compareTo(t1.getName());
}
});
try {
Class> modelClass = loadClass("org.glassfish.admin.rest.resources.composite.Job");
classes.add(getCompositeUtil().getModel(modelClass).getClass());
modelClass = loadClass("org.glassfish.admin.rest.resources.composite.Dummy");
classes.add(getCompositeUtil().getModel(modelClass).getClass());
} catch (ClassNotFoundException ex) {
RestLogging.restLogger.log(Level.WARNING, null, ex);
}
JAXBContext jc = JAXBContext.newInstance(classes.toArray(Class[]::new));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
jc.generateSchema(new MySchemaOutputResolver(baos));
return new String(baos.toByteArray(), UTF_8);
}
@GET
public String getSchemaManually() {
StringBuilder sb = new StringBuilder("\n"
+ "\n");
// + "\t\n");
StringBuilder complexTypes = new StringBuilder();
addElement(sb, "object");
processClass(complexTypes, Object.class, "object");
for (String c : locateRestModels()) {
try {
Class> modelClass = getCompositeUtil().getModel(loadClass(c)).getClass();
String simpleName = modelClass.getSimpleName().toLowerCase(Locale.getDefault());
if (simpleName.endsWith("impl")) {
simpleName = simpleName.substring(0, simpleName.length() - 4);
}
addElement(sb, simpleName);
processClass(complexTypes, modelClass, simpleName);
} catch (ClassNotFoundException ex) {
RestLogging.restLogger.log(Level.WARNING, null, ex);
}
}
sb.append(complexTypes);
return sb.append(" \n").toString();
}
/*
* TODO: This is a bit ugly, but JAXB doesn't seem to like the way we're doing models. When
* time permits, it may be best to revisit this and see why JAXB dies when given, for example,
* a List or Object return type. Once that's resolved, we may be able to use JAXB serialization.
*/
protected void processClass(StringBuilder sb, Class> c, String simpleName) {
sb.append("\t\n\t\t\n");
for (Class> i : c.getInterfaces()) {
for (Method m : i.getDeclaredMethods()) {
String name = m.getName();
if (name.startsWith("get") && !"getClass".equals(name)) {
name = name.substring(3, 4).toLowerCase(Locale.getDefault()) + name.substring(4);
Class> returnType = m.getReturnType();
sb.append("\t\t\t) rt.getActualTypeArguments()[0];
sb.append(getType(returnType)).append(" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"unbounded\"");
}
sb.append("/>\n");
}
}
}
sb.append("\t\t \n\t \n");
}
private String getType(Class> clazz) {
if (clazz.isPrimitive()) {
return "type=\"xs:" + clazz.getSimpleName() + "\"";
} else if (WRAPPER_TYPES.contains(clazz) || String.class.equals(clazz)) {
return "type=\"xs:" + clazz.getSimpleName().toLowerCase(Locale.getDefault()) + "\"";
} else {
return "type=\"" + clazz.getSimpleName().toLowerCase(Locale.getDefault()) + "\"";
}
}
private static final Set> WRAPPER_TYPES = new HashSet() {
{
add(Boolean.class);
add(Character.class);
add(Byte.class);
add(Short.class);
add(Integer.class);
add(Long.class);
add(Float.class);
add(Double.class);
add(Void.class);
}
};
private Set locateRestModels() {
Set classes = new HashSet<>();
List> widgetDescriptors = Globals.getDefaultBaseServiceLocator()
.getDescriptors(BuilderHelper.createContractFilter(RestModel.class.getName()));
for (ActiveDescriptor ad : widgetDescriptors) {
classes.add(ad.getImplementation());
}
return classes;
}
private Class> loadClass(String className) throws ClassNotFoundException {
try {
return Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException ex) {
return getClass().getClassLoader().loadClass(className);
}
}
private void addElement(StringBuilder sb, String simpleName) {
sb.append("\t\n");
}
private static class MySchemaOutputResolver extends SchemaOutputResolver {
ByteArrayOutputStream baos;
private MySchemaOutputResolver(ByteArrayOutputStream baos) {
this.baos = baos;
}
@Override
public javax.xml.transform.Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
StreamResult r = new StreamResult("argh");
r.setOutputStream(baos);
return r;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy