All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.arachnidium.model.abstractions.ModelObject Maven / Gradle / Ivy

The newest version!
/*
 +Copyright 2014 Arachnidium contributors
 +Copyright 2014 Software Freedom Conservancy
 +
 +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 com.github.arachnidium.model.abstractions;

import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.internal.WrapsDriver;

import com.github.arachnidium.core.BrowserWindow;
import com.github.arachnidium.core.Handle;
import com.github.arachnidium.core.MobileScreen;
import com.github.arachnidium.core.WebDriverEncapsulation;
import com.github.arachnidium.core.components.WebdriverComponent;
import com.github.arachnidium.core.components.common.Awaiting;
import com.github.arachnidium.core.components.common.DriverLogs;
import com.github.arachnidium.core.interfaces.IDestroyable;
import com.github.arachnidium.model.interfaces.IDecomposable;
import com.github.arachnidium.model.interfaces.IModelObjectExceptionHandler;
import com.github.arachnidium.model.support.HowToGetByFrames;
import com.github.arachnidium.util.reflect.annotations.AnnotationUtil;

/**
 * This is a basic abstraction 
 * which describes objects are used for modeling application.
 * 
 * @param  It means that objects can be stationed on browser window or mobile application screen.
* * If there is
* <S extends {@link Handle}> or
* * <{@link Handle}> it means that * both {@link BrowserWindow} and {@link MobileScreen} are possible. It is good * for situations when interaction with UI of browser client and the perfectly similar mobile client * has to be automated.
*
* If it needs to be bounded by only one {@link Handle} subclass ({@link BrowserWindow} or {@link MobileScreen}) * then
* - <{@link BrowserWindow}> - only browser windows
*
* or
*
* - <{@link MobileScreen}> - only mobile screens */ public abstract class ModelObject implements IDestroyable, IDecomposable, WrapsDriver { protected final S handle; //window or mobile context. This object is stationed on it. private final WebDriverEncapsulation driverEncapsulation; protected final Awaiting awaiting; //performs waiting protected final DriverLogs logs; //is for getting WebDriver logs //this is for interception and automatically handling exceptions protected final HashSet checkedInExceptionHandlers = new HashSet(); // this will be invoked when some exception is caught out IModelObjectExceptionHandler exceptionHandler = (IModelObjectExceptionHandler) Proxy .newProxyInstance( IModelObjectExceptionHandler.class.getClassLoader(), new Class[] { IModelObjectExceptionHandler.class }, (proxy, method, args) -> { // it needs to know exception Throwable t = (Throwable) args[4]; for (ModelObjectExceptionHandler handler : checkedInExceptionHandlers) // it looks for the suitable handler if (handler.isThrowableInList(t.getClass())) try { return method.invoke(handler, args); } catch (Exception e) { continue; // it wasn't the suitable // handler } // if there are no suitable handlers throw t; }); @SuppressWarnings("rawtypes") final List children = Collections .synchronizedList(new ArrayList()); /** * This is the general constructor. * * @param handle is the given browser window or * mobile context which currently present * */ protected ModelObject(S handle) { this.handle = handle; driverEncapsulation = handle.driverEncapsulation; awaiting = new Awaiting(driverEncapsulation.getWrappedDriver()); logs = driverEncapsulation.getComponent(DriverLogs.class); UsedImplicitExceptionHandlers[] annotations = AnnotationUtil.getAnnotations( UsedImplicitExceptionHandlers.class, this.getClass(), true); if (annotations.length != 0) { UsedImplicitExceptionHandlers ueh = annotations[0]; List> throwableHandlers = Arrays .asList(ueh.areUsed()); throwableHandlers.forEach((handler) -> { try { checkInExceptionHandler(handler.newInstance()); } catch (Exception e) { throw new RuntimeException(e); } }); } } /** * Adds the child object * * @param child is the child {@link ModelObject} */ protected void addChild(ModelObject child) { children.add(child); } /** * This method add an object that * performs automatically handling of * some caught exception. * * @param exceptionHandler is the object which * performs automatically handling of * some caught exception * * @see ModelObjectExceptionHandler * * @see IModelObjectExceptionHandler */ public void checkInExceptionHandler( ModelObjectExceptionHandler exceptionHandler) { checkedInExceptionHandlers.add(exceptionHandler); } public void checkOutExceptionHandler( ModelObjectExceptionHandler exceptionHandler) { checkedInExceptionHandlers.remove(exceptionHandler); } /** * This method destroys information * about child objects */ @Override public void destroy() { for (ModelObject child : children) child.destroy(); children.clear(); } /** * @see com.github.arachnidium.model.interfaces.IDecomposable#getPart(java.lang.Class) */ @Override public abstract T getPart(Class partClass); /** * @see com.github.arachnidium.model.interfaces.IDecomposable#getPart(java.lang.Class, com.github.arachnidium.model.support.HowToGetByFrames) * * @see HowToGetByFrames */ @Override public abstract T getPart(Class partClass, HowToGetByFrames pathStrategy); /** * @see IDecomposable#getPart(Class, By) */ @Override public abstract T getPart(Class partClass, By by); /** * @see IDecomposable#getPart(Class, HowToGetByFrames, By) */ @Override public abstract T getPart(Class partClass, HowToGetByFrames pathStrategy, By by); /** * @see org.openqa.selenium.internal.WrapsDriver#getWrappedDriver() */ @Override public WebDriver getWrappedDriver() { return driverEncapsulation.getWrappedDriver(); } /** * @param required {@link WebdriverComponent} subclass * @return The instance of required {@link WebdriverComponent} subclass * * It is supposed to be for internal usage */ protected final T getComponent(Class required) { return driverEncapsulation.getComponent(required); } /** * * @param required {@link WebdriverComponent} subclass * * @param params is a Class[] which excludes {@link WebDriver}.class * {@link WebDriver} + given Class[] should match to {@link WebdriverComponent} subclass * constructor parameters * * @param values is a Object[] which excludes {@link WebDriver} instance * {@link WebDriver} instance + given Object[] should match to {@link WebdriverComponent} subclass * constructor * * @return The instance of required {@link WebdriverComponent} subclass * * It is supposed to be for internal usage */ protected final T getComponent(Class required, Class[] params, Object[] values) { return driverEncapsulation.getComponent(required, params, values); } public final WebDriverEncapsulation getWebDriverEncapsulation(){ return driverEncapsulation; } public Handle getHandle(){ return handle; } }