--- /dev/null
+package com.vaadin.tests.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.net.URI;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Allows to get classes from the current classpath using classes FQN filter.
+ * <p>
+ * The methods in the class return all real (not anonymous and not private)
+ * classes from the filtered classpath.
+ *
+ * @author Vaadin Ltd
+ *
+ */
+class ClasspathHelper {
+
+ private final Predicate<String> skipClassesFilter;
+
+ ClasspathHelper(Predicate<String> skipClassesFilter) {
+ this.skipClassesFilter = skipClassesFilter;
+ }
+
+ Stream<Class<?>> getVaadinClassesFromClasspath(
+ Predicate<String> classpathFilter,
+ Predicate<Class<?>> classFilter) {
+ return getRawClasspathEntries().stream().filter(classpathFilter)
+ .map(File::new).map(file -> getVaadinClassesFromFile(file))
+ .flatMap(List::stream).filter(classFilter)
+ .filter(cls -> !cls.isSynthetic() && !cls.isAnonymousClass()
+ && !Modifier.isPrivate(cls.getModifiers()));
+
+ }
+
+ Stream<Class<?>> getVaadinClassesFromClasspath(
+ Predicate<String> classpathFilter) {
+ return getVaadinClassesFromClasspath(classpathFilter, cls -> true);
+ }
+
+ private List<Class<?>> getVaadinClassesFromFile(File classesRoot) {
+ try {
+ if (classesRoot.isDirectory()) {
+ return Files.walk(classesRoot.toPath())
+ .filter(Files::isRegularFile)
+ .filter(path -> path.toFile().getName()
+ .endsWith(".class"))
+ .filter(path -> classesRoot.toPath().relativize(path)
+ .toString().contains("com/vaadin/"))
+ .map(path -> getClassFromFile(path,
+ classesRoot.toPath()))
+ .filter(Objects::nonNull).collect(Collectors.toList());
+ } else if (classesRoot.getName().toLowerCase(Locale.ENGLISH)
+ .endsWith(".jar")) {
+ URI uri = URI.create("jar:file:" + classesRoot.getPath());
+ Path root = FileSystems
+ .newFileSystem(uri, Collections.emptyMap())
+ .getPath("/");
+ return Files.walk(root).filter(Files::isRegularFile)
+ .filter(path -> path.toUri().getSchemeSpecificPart()
+ .endsWith(".class"))
+ .filter(path -> root.relativize(path).toString()
+ .contains("com/vaadin/"))
+ .map(path -> getClassFromFile(path, root))
+ .filter(Objects::nonNull).collect(Collectors.toList());
+ }
+ return null;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Class<?> getClassFromFile(Path path, Path root) {
+ Path relative = root.relativize(path);
+ String name = relative.toString();
+ name = name.substring(0, name.length() - ".class".length());
+ name = name.replace('/', '.');
+ if (skipClassesFilter.test(name)) {
+ return null;
+ }
+ try {
+ return Class.forName(name, false, getClass().getClassLoader());
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private final static List<String> getRawClasspathEntries() {
+ List<String> locations = new ArrayList<>();
+
+ String pathSep = System.getProperty("path.separator");
+ String classpath = System.getProperty("java.class.path");
+
+ if (classpath.startsWith("\"")) {
+ classpath = classpath.substring(1);
+ }
+ if (classpath.endsWith("\"")) {
+ classpath = classpath.substring(0, classpath.length() - 1);
+ }
+
+ String[] split = classpath.split(pathSep);
+ for (int i = 0; i < split.length; i++) {
+ String classpathEntry = split[i];
+ locations.add(classpathEntry);
+ }
+
+ return locations;
+ }
+
+}
--- /dev/null
+package com.vaadin.tests.server;
+
+import java.io.File;
+import java.lang.reflect.Modifier;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.navigator.Navigator;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.DragAndDropWrapper;
+import com.vaadin.ui.components.colorpicker.ColorPickerGradient;
+import com.vaadin.ui.components.colorpicker.ColorPickerGrid;
+import com.vaadin.ui.components.colorpicker.ColorPickerHistory;
+import com.vaadin.ui.components.colorpicker.ColorPickerPopup;
+import com.vaadin.ui.components.colorpicker.ColorPickerPreview;
+import com.vaadin.ui.components.colorpicker.ColorPickerSelect;
+import com.vaadin.ui.declarative.Design;
+import com.vaadin.ui.declarative.DesignAttributeHandler;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Utility class for outputting the declarative syntax of Vaadin components.
+ */
+public class ComponentDesignWriterUtility {
+
+ private static final Set<String> WHITE_LIST_FQNS = new HashSet<>();
+ static {
+ WHITE_LIST_FQNS.add(DragAndDropWrapper.class.getName());
+ WHITE_LIST_FQNS.add(Navigator.EmptyView.class.getName());
+
+ WHITE_LIST_FQNS.add(ColorPickerGradient.class.getName());
+ WHITE_LIST_FQNS.add(ColorPickerPopup.class.getName());
+ WHITE_LIST_FQNS.add(ColorPickerPreview.class.getName());
+ WHITE_LIST_FQNS.add(ColorPickerGrid.class.getName());
+ WHITE_LIST_FQNS.add(ColorPickerSelect.class.getName());
+ WHITE_LIST_FQNS.add(ColorPickerHistory.class.getName());
+
+ WHITE_LIST_FQNS
+ .add(com.vaadin.v7.ui.components.colorpicker.ColorPickerGradient.class
+ .getName());
+ WHITE_LIST_FQNS
+ .add(com.vaadin.v7.ui.components.colorpicker.ColorPickerPopup.class
+ .getName());
+ WHITE_LIST_FQNS
+ .add(com.vaadin.v7.ui.components.colorpicker.ColorPickerPreview.class
+ .getName());
+ WHITE_LIST_FQNS
+ .add(com.vaadin.v7.ui.components.colorpicker.ColorPickerGrid.class
+ .getName());
+ WHITE_LIST_FQNS
+ .add(com.vaadin.v7.ui.components.colorpicker.ColorPickerSelect.class
+ .getName());
+ WHITE_LIST_FQNS
+ .add(com.vaadin.v7.ui.components.colorpicker.ColorPickerHistory.class
+ .getName());
+
+ // ==================================================================
+ // Classes that cannot be loaded
+ // ==================================================================
+ WHITE_LIST_FQNS.add(
+ "com.vaadin.server.communication.PushAtmosphereHandler$AtmosphereResourceListener");
+ WHITE_LIST_FQNS
+ .add("com.vaadin.server.communication.PushAtmosphereHandler");
+ WHITE_LIST_FQNS
+ .add("com.vaadin.server.communication.PushRequestHandler$2");
+ WHITE_LIST_FQNS.add("com.vaadin.server.LegacyVaadinPortlet");
+ WHITE_LIST_FQNS.add("com.vaadin.server.RestrictedRenderResponse");
+ WHITE_LIST_FQNS
+ .add("com.vaadin.server.VaadinPortlet$VaadinGateInRequest");
+ WHITE_LIST_FQNS.add(
+ "com.vaadin.server.VaadinPortlet$VaadinHttpAndPortletRequest");
+ WHITE_LIST_FQNS
+ .add("com.vaadin.server.VaadinPortlet$VaadinLiferayRequest");
+ WHITE_LIST_FQNS.add(
+ "com.vaadin.server.VaadinPortlet$VaadinWebLogicPortalRequest");
+ WHITE_LIST_FQNS.add(
+ "com.vaadin.server.VaadinPortlet$VaadinWebSpherePortalRequest");
+ WHITE_LIST_FQNS.add("com.vaadin.server.VaadinPortlet");
+ WHITE_LIST_FQNS.add("com.vaadin.server.VaadinPortletRequest");
+ }
+
+ private static final Document document = new Document("");
+ private static final DesignContext designContext = new DesignContext(
+ document);
+
+ @SafeVarargs
+ public static List<String> getDeclarativeSyntax(
+ Class<? extends Component>... components) {
+ return getDeclarativeSyntax(Arrays.asList(components));
+ }
+
+ public static List<String> getDeclarativeSyntax(
+ List<Class<? extends Component>> components) {
+ DesignAttributeHandler.setWriteDefaultValues(true);
+
+ List<String> declarativeStrings = components.stream()
+ .map(ComponentDesignWriterUtility::getDeclarativeSyntax)
+ .collect(Collectors.toList());
+
+ DesignAttributeHandler.setWriteDefaultValues(false);
+ return declarativeStrings;
+ }
+
+ @Test
+ public void vaadin8ComponentsElementStartsWithVaadinPrefix()
+ throws URISyntaxException {
+ Assert.assertTrue(getVaadin8Components().stream()
+ .map(ComponentDesignWriterUtility::getDeclarativeSyntax)
+ .allMatch(element -> element.startsWith("<vaadin-")));
+ }
+
+ @Test
+ public void vaadin7ComponentsElementStartsWithVaadinPrefix()
+ throws URISyntaxException {
+ Assert.assertTrue(getVaadin7Components().stream()
+ .map(ComponentDesignWriterUtility::getDeclarativeSyntax)
+ .allMatch(element -> element.startsWith("<vaadin7-")));
+ }
+
+ private static String getDeclarativeSyntax(
+ Class<? extends Component> componentClass) {
+ try {
+ Component component = componentClass.newInstance();
+ Element element = document.createElement(Design.getComponentMapper()
+ .componentToTag(component, designContext));
+ component.writeDesign(element, designContext);
+ return element.toString();
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Could not write the declarative syntax for component "
+ + componentClass.getName(),
+ e);
+ }
+ }
+
+ public static void main(String[] args) throws URISyntaxException {
+ System.out.println("Vaadin 8 components:");
+ printFullDeclarativeSyntax(getVaadin8Components());
+
+ System.out.println("Vaadin 7 components:");
+ printFullDeclarativeSyntax(getVaadin7Components());
+
+ System.out.println("\nClases that are explicitely excluded from "
+ + "the design support introspection:");
+ WHITE_LIST_FQNS.forEach(System.out::println);
+ }
+
+ private static void printFullDeclarativeSyntax(
+ List<Class<? extends Component>> components) {
+ DesignAttributeHandler.setWriteDefaultValues(true);
+ components.stream().forEach(component -> System.out
+ .println(getDeclarativeSyntax(component)));
+ DesignAttributeHandler.setWriteDefaultValues(false);
+ }
+
+ private static List<Class<? extends Component>> getVaadin8Components()
+ throws URISyntaxException {
+ List<Class<? extends Component>> vaadin8Components = getVaadinComponentsFromClasspath(
+ "/server/target/classes");
+ if (vaadin8Components.isEmpty()) {
+ throw new RuntimeException(
+ "No vaadin 8 components found on your classpath.");
+ }
+ return vaadin8Components;
+ }
+
+ private static List<Class<? extends Component>> getVaadin7Components()
+ throws URISyntaxException {
+ List<Class<? extends Component>> vaadin7Components = getVaadinComponentsFromClasspath(
+ "compatibility-server");
+ if (vaadin7Components.isEmpty()) {
+ throw new RuntimeException(
+ "No vaadin 7 components found on your classpath.");
+ }
+ return vaadin7Components;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List<Class<? extends Component>> getVaadinComponentsFromClasspath(
+ String classpathFilter) throws URISyntaxException {
+ File testRoot = new File(
+ ComponentDesignWriterUtility.class.getResource("/").toURI());
+ List<Class<? extends Component>> classes = new ClasspathHelper(
+ WHITE_LIST_FQNS::contains).getVaadinClassesFromClasspath(
+ entry -> entry.contains(classpathFilter)
+ && !testRoot.equals(new File(entry)),
+ cls -> Component.class.isAssignableFrom(cls)
+ && !cls.isInterface()
+ && !Modifier.isAbstract(cls.getModifiers()))
+ .map(cls -> (Class<? extends Component>) cls)
+ .collect(Collectors.toList());
+ return classes;
+ }
+
+}
package com.vaadin.tests.server;
import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Modifier;
-import java.net.URI;
import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.stream.Collectors;
+import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Assert;
import org.junit.Test;
*/
public class DeprecatedTest {
- private static String CLASS_SUFFIX = ".class";
-
@Test
public void allTypesAreDeprecated() throws URISyntaxException {
- URL url = DeprecatedTest.class.getResource("/");
- File file = new File(url.toURI());
- List<File> classpath = getRawClasspathEntries().stream()
- .filter(entry -> entry.contains("compatibility-server"))
- .map(File::new).filter(fileEntry -> !fileEntry.equals(file))
- .collect(Collectors.toList());
- Assert.assertFalse(classpath.isEmpty());
- classpath.forEach(this::checkDeprecatedClasses);
- }
-
- private void checkDeprecatedClasses(File classesRoot) {
- try {
- if (classesRoot.isDirectory()) {
- Files.walk(classesRoot.toPath()).filter(Files::isRegularFile)
- .filter(path -> path.toFile().getName()
- .endsWith(CLASS_SUFFIX))
- .forEach(path -> checkDeprecatedClass(path,
- classesRoot.toPath()));
- } else if (classesRoot.getName().toLowerCase(Locale.ENGLISH)
- .endsWith(".jar")) {
- URI uri = URI.create("jar:file:" + classesRoot.getPath());
- Path root = FileSystems
- .newFileSystem(uri, Collections.emptyMap())
- .getPath("/");
- Files.walk(root).filter(Files::isRegularFile)
- .filter(path -> path.toUri().getSchemeSpecificPart()
- .endsWith(CLASS_SUFFIX))
- .forEach(path -> checkDeprecatedClass(path, root));
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- private void checkDeprecatedClass(Path path, Path root) {
- Path relative = root.relativize(path);
- String name = relative.toString();
- name = name.substring(0, name.length() - CLASS_SUFFIX.length());
- name = name.replace('/', '.');
- try {
- Class<?> clazz = Class.forName(name);
- if (clazz.isSynthetic() || clazz.isAnonymousClass()) {
- return;
- }
- if (Modifier.isPrivate(clazz.getModifiers())) {
- return;
- }
- Assert.assertNotNull(
- "Class " + clazz
- + " is in compatability package and it's not deprecated",
- clazz.getAnnotation(Deprecated.class));
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
+ AtomicInteger count = new AtomicInteger(0);
+
+ File testRoot = new File(DeprecatedTest.class.getResource("/").toURI());
+
+ new ClasspathHelper(fqn -> false)
+ .getVaadinClassesFromClasspath(
+ entry -> entry.contains("compatibility-server")
+ && !testRoot.equals(new File(entry)))
+ .forEach(cls -> {
+ count.incrementAndGet();
+ Assert.assertNotNull(
+ "Class " + cls
+ + " is in compatability package and it's not deprecated",
+ cls.getAnnotation(Deprecated.class));
+ });
+ Assert.assertTrue(count.get() > 0);
}
- private final static List<String> getRawClasspathEntries() {
- // try to keep the order of the classpath
- List<String> locations = new ArrayList<>();
-
- String pathSep = System.getProperty("path.separator");
- String classpath = System.getProperty("java.class.path");
-
- if (classpath.startsWith("\"")) {
- classpath = classpath.substring(1);
- }
- if (classpath.endsWith("\"")) {
- classpath = classpath.substring(0, classpath.length() - 1);
- }
-
- String[] split = classpath.split(pathSep);
- for (int i = 0; i < split.length; i++) {
- String classpathEntry = split[i];
- locations.add(classpathEntry);
- }
-
- return locations;
- }
}
import java.io.IOException;
import java.util.List;
+import com.vaadin.ui.Component;
import com.vaadin.v7.ui.Field;
@SuppressWarnings("deprecation")
public static List<Class<? extends Field>> getFields() {
try {
return com.vaadin.tests.VaadinClasses.findClasses(Field.class,
- "com.vaadin.ui");
+ "com.vaadin.v7.ui");
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
+ public static List<Class<? extends Component>> getComponents() {
+ try {
+ return com.vaadin.tests.VaadinClasses.findClasses(Component.class,
+ "com.vaadin.v7.ui");
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Could not find all Vaadin component classes", e);
+ }
+ }
}
// translates string <-> object
private static DesignFormatter FORMATTER = new DesignFormatter();
+ private static boolean writeDefaultValues = false;
+
+ /**
+ * Set whether default attribute values should be written by the
+ * {@code DesignAttributeHandler#writeAttribute(String, Attributes, Object, Object, Class)}
+ * method. Default is {@code false}.
+ *
+ * @param value
+ * {@code true} to write default values of attributes,
+ * {@code false} to disable writing of default values
+ */
+ public static void setWriteDefaultValues(boolean value) {
+ writeDefaultValues = value;
+ }
+
/**
* Returns the currently used formatter. All primitive types and all types
* needed by Vaadin components are handled by that formatter.
throw new IllegalArgumentException(
"input type: " + inputType.getName() + " not supported");
}
- if (!SharedUtil.equals(value, defaultValue)) {
+ if (writeDefaultValues || !SharedUtil.equals(value, defaultValue)) {
String attributeValue = toAttributeValue(inputType, value);
if ("".equals(attributeValue) && (inputType == boolean.class
|| inputType == Boolean.class)) {
String value) {
Map<String, String> map = customAttributes.get(component);
if (map == null) {
- customAttributes.put(component,
- map = new HashMap<>());
+ customAttributes.put(component, map = new HashMap<>());
}
map.put(attribute, value);
}