/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2014 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.server.ngclient.property; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.security.Principal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.websocket.CloseReason; import javax.websocket.EncodeException; import javax.websocket.Extension; import javax.websocket.MessageHandler; import javax.websocket.MessageHandler.Partial; import javax.websocket.MessageHandler.Whole; import javax.websocket.RemoteEndpoint.Async; import javax.websocket.RemoteEndpoint.Basic; import javax.websocket.Session; import javax.websocket.WebSocketContainer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.sablo.InMemPackageReader; import org.sablo.specification.NGPackage; import org.sablo.specification.NGPackage.IPackageReader; import org.sablo.specification.WebComponentSpecProvider; import org.sablo.specification.WebServiceSpecProvider; import org.sablo.websocket.CurrentWindow; import org.sablo.websocket.WebsocketSessionManager; import com.servoy.j2db.J2DBGlobals; import com.servoy.j2db.persistence.ChangeHandler; import com.servoy.j2db.persistence.IRepository; import com.servoy.j2db.persistence.IValidateName; import com.servoy.j2db.persistence.RepositoryException; import com.servoy.j2db.persistence.RootObjectMetaData; import com.servoy.j2db.persistence.Solution; import com.servoy.j2db.persistence.SolutionMetaData; import com.servoy.j2db.persistence.ValidatorSearchContext; import com.servoy.j2db.server.ngclient.FormElementHelper; import com.servoy.j2db.server.ngclient.INGClientWebsocketSession; import com.servoy.j2db.server.ngclient.endpoint.NGClientEndpoint; import com.servoy.j2db.server.ngclient.eventthread.NGClientWebsocketSessionWindows; import com.servoy.j2db.server.ngclient.property.types.Types; import com.servoy.j2db.server.shared.ApplicationServerRegistry; import com.servoy.j2db.util.Debug; import com.servoy.j2db.util.ServoyException; import com.servoy.j2db.util.UUID; import com.servoy.j2db.util.Utils; /** * @author jcompagner * */ public abstract class AbstractSolutionTest { private static IPackageReader[] getReaders(File[] packages, IPackageReader customComponents) { ArrayList<IPackageReader> readers = new ArrayList<>(); if (customComponents != null) readers.add(customComponents); for (File f : packages) { if (f.exists()) { if (f.isDirectory()) readers.add(new NGPackage.DirPackageReader(f)); else readers.add(new NGPackage.JarPackageReader(f)); } else { Debug.error("A web component package location does not exist: " + f.getAbsolutePath()); //$NON-NLS-1$ } } return readers.toArray(new IPackageReader[readers.size()]); } protected IValidateName validator = new IValidateName() { @Override public void checkName(String nameToCheck, int skip_element_id, ValidatorSearchContext searchContext, boolean sqlRelated) throws RepositoryException { } }; protected Solution solution; protected TestNGClient client; protected NGClientEndpoint endpoint; /** * */ public AbstractSolutionTest() { super(); } private static class ZipPackageReader implements NGPackage.IPackageReader { private final ZipFile file; private final String pathPrefix; public ZipPackageReader(ZipFile file, String pathPrefix) { this.file = file; this.pathPrefix = pathPrefix; } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#getName() */ @Override public String getName() { String[] split = file.getEntry(pathPrefix).getName().split("/"); return split[split.length - 1].replace("/", ""); } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#getPackageName() */ @Override public String getPackageName() { try { String packageDisplayname = NGPackage.getPackageName(getManifest()); if (packageDisplayname != null) return packageDisplayname; } catch (IOException e) { Debug.log(e); } // fall back to symbolic name return getName(); } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#getPackageDisplayname() */ @Override public String getPackageDisplayname() { try { String packageDisplayname = NGPackage.getPackageDisplayname(getManifest()); if (packageDisplayname != null) return packageDisplayname; } catch (IOException e) { Debug.log(e); } // fall back to symbolic name return getPackageName(); } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#getManifest() */ @Override public Manifest getManifest() throws IOException { ZipEntry m = file.getEntry(pathPrefix + "META-INF/MANIFEST.MF"); try (InputStream is = file.getInputStream(m)) { return new Manifest(is); } } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#readTextFile(java.lang.String, java.nio.charset.Charset) */ @Override public String readTextFile(String path, Charset charset) throws IOException { ZipEntry m = file.getEntry(pathPrefix + path); try (InputStream is = file.getInputStream(m)) { return Utils.getTXTFileContent(is, charset); } } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#getUrlForPath(java.lang.String) */ @Override public URL getUrlForPath(String path) throws MalformedURLException { return null; } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#getPackageURL() */ @Override public URL getPackageURL() { return null; } /* * (non-Javadoc) * * @see org.sablo.specification.WebComponentPackage.IPackageReader#reportError(java.lang.String, java.lang.Exception) */ @Override public void reportError(String specpath, Exception e) { System.err.println(e.getMessage()); } } @Before public void buildSolution() throws Exception { Types.getTypesInstance().registerTypes(); final File f = new File(PersistFieldInstanceTest.class.getProtectionDomain().getCodeSource().getLocation().getPath()); IPackageReader[] servicesReaders = null; IPackageReader[] componentsReaders = null; InMemPackageReader inMemPackageReader = getTestComponents(); if (f.isFile() && f.getName().startsWith("servoy_ngclient_") && f.getName().endsWith(".jar")) { ZipFile zipFile = new ZipFile(f); componentsReaders = inMemPackageReader != null ? new IPackageReader[] { new ZipPackageReader(zipFile, "war/servoycore/"), new ZipPackageReader( zipFile, "war/servoydefault/"), inMemPackageReader } : new IPackageReader[] { new ZipPackageReader(zipFile, "war/servoycore/"), new ZipPackageReader(zipFile, "war/servoydefault/") }; servicesReaders = new IPackageReader[] { new ZipPackageReader(zipFile, "war/servoyservices/") }; } else { componentsReaders = getReaders(new File[] { new File(f.getAbsoluteFile() + "/../war/servoycore/"), new File(f.getAbsoluteFile() + "/../war/servoydefault/") }, inMemPackageReader); //in eclipse we .. out of bin, in jenkins we .. out of @dot servicesReaders = getReaders(new File[] { new File(f.getAbsoluteFile(), "/../war/servoyservices/") }, null); } WebComponentSpecProvider.init(componentsReaders); WebServiceSpecProvider.init(servicesReaders); final TestRepository tr = new TestRepository(); try { ApplicationServerRegistry.setApplicationServerSingleton(new TestApplicationServer(tr)); UUID uuid = UUID.randomUUID(); final RootObjectMetaData metadata = tr.createRootObjectMetaData(tr.getElementIdForUUID(uuid), uuid, "Test", IRepository.SOLUTIONS, 1, 1); solution = (Solution)tr.createRootObject(metadata); tr.cacheRootObject(solution); solution.setChangeHandler(new ChangeHandler(tr)); fillTestSolution(); client = new TestNGClient(tr) { @Override public boolean loadSolutionsAndModules(SolutionMetaData solutionMetaData) { boolean b = super.loadSolutionsAndModules(solutionMetaData); try { setupData(); } catch (ServoyException e) { e.printStackTrace(); } return b; } @Override public boolean isInDesigner() { // to prevent some caching which causes tests to influence each other return true; } }; J2DBGlobals.setServiceProvider(client); client.setUseLoginSolution(false); endpoint = new NGClientEndpoint(); endpoint.start(new Session() { @Override public void setMaxTextMessageBufferSize(int arg0) { } @Override public void setMaxIdleTimeout(long arg0) { } @Override public void setMaxBinaryMessageBufferSize(int arg0) { // TODO Auto-generated method stub } @Override public void removeMessageHandler(MessageHandler arg0) { // TODO Auto-generated method stub } @Override public boolean isSecure() { // TODO Auto-generated method stub return false; } @Override public boolean isOpen() { // TODO Auto-generated method stub return false; } @Override public Map<String, Object> getUserProperties() { // TODO Auto-generated method stub return null; } @Override public Principal getUserPrincipal() { // TODO Auto-generated method stub return null; } @Override public URI getRequestURI() { // TODO Auto-generated method stub return null; } @Override public Map<String, List<String>> getRequestParameterMap() { return Collections.singletonMap("solution", Arrays.asList("Test")); } @Override public String getQueryString() { // TODO Auto-generated method stub return null; } @Override public String getProtocolVersion() { // TODO Auto-generated method stub return null; } @Override public Map<String, String> getPathParameters() { // TODO Auto-generated method stub return null; } @Override public Set<Session> getOpenSessions() { // TODO Auto-generated method stub return null; } @Override public String getNegotiatedSubprotocol() { // TODO Auto-generated method stub return null; } @Override public List<Extension> getNegotiatedExtensions() { // TODO Auto-generated method stub return null; } @Override public Set<MessageHandler> getMessageHandlers() { // TODO Auto-generated method stub return null; } @Override public int getMaxTextMessageBufferSize() { // TODO Auto-generated method stub return 0; } @Override public long getMaxIdleTimeout() { // TODO Auto-generated method stub return 0; } @Override public int getMaxBinaryMessageBufferSize() { // TODO Auto-generated method stub return 0; } @Override public String getId() { // TODO Auto-generated method stub return null; } @Override public WebSocketContainer getContainer() { // TODO Auto-generated method stub return null; } @Override public Basic getBasicRemote() { return new Basic() { @Override public void setBatchingAllowed(boolean arg0) throws IOException { // TODO Auto-generated method stub } @Override public void sendPong(ByteBuffer arg0) throws IOException, IllegalArgumentException { // TODO Auto-generated method stub } @Override public void sendPing(ByteBuffer arg0) throws IOException, IllegalArgumentException { // TODO Auto-generated method stub } @Override public boolean getBatchingAllowed() { // TODO Auto-generated method stub return false; } @Override public void flushBatch() throws IOException { // TODO Auto-generated method stub } @Override public void sendText(String arg0, boolean arg1) throws IOException { // TODO Auto-generated method stub } @Override public void sendText(String arg0) throws IOException { // TODO Auto-generated method stub } @Override public void sendObject(Object arg0) throws IOException, EncodeException { // TODO Auto-generated method stub } @Override public void sendBinary(ByteBuffer arg0, boolean arg1) throws IOException { // TODO Auto-generated method stub } @Override public void sendBinary(ByteBuffer arg0) throws IOException { // TODO Auto-generated method stub } @Override public Writer getSendWriter() throws IOException { // TODO Auto-generated method stub return null; } @Override public OutputStream getSendStream() throws IOException { // TODO Auto-generated method stub return null; } }; } @Override public Async getAsyncRemote() { // TODO Auto-generated method stub return null; } @Override public void close(CloseReason arg0) throws IOException { // TODO Auto-generated method stub } @Override public void close() throws IOException { // TODO Auto-generated method stub } @Override public <T> void addMessageHandler(Class<T> arg0, Whole<T> arg1) throws IllegalStateException { // TODO Auto-generated method stub } @Override public <T> void addMessageHandler(Class<T> arg0, Partial<T> arg1) throws IllegalStateException { // TODO Auto-generated method stub } @Override public void addMessageHandler(MessageHandler arg0) throws IllegalStateException { // TODO Auto-generated method stub } }, "1", null, "Test"); INGClientWebsocketSession wsSession = (INGClientWebsocketSession)WebsocketSessionManager.getSession(endpoint.getEndpointType(), "1"); Assert.assertNotNull("no wsSession", wsSession); CurrentWindow.set(new NGClientWebsocketSessionWindows(wsSession)); } catch (RepositoryException e) { e.printStackTrace(); Assert.fail(e.getMessage()); } } @After public void tearDown() throws Exception { CurrentWindow.set(null); FormElementHelper.INSTANCE.reload(); ApplicationServerRegistry.clear(); } protected abstract void setupData() throws ServoyException; /** * @throws RepositoryException * @throws ServoyException */ protected abstract void fillTestSolution() throws ServoyException; /** * @return * @throws IOException */ protected abstract InMemPackageReader getTestComponents() throws IOException; }