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

com.webfirmframework.wffweb.css.Margin Maven / Gradle / Ivy

There is a newer version: 12.0.1
Show newest version
/*
 * Copyright 2014-2016 Web Firm Framework
 *
 * 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.webfirmframework.wffweb.css;

import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

import com.webfirmframework.wffweb.InvalidValueException;
import com.webfirmframework.wffweb.NullValueException;
import com.webfirmframework.wffweb.css.core.AbstractCssProperty;
import com.webfirmframework.wffweb.css.core.CssProperty;
import com.webfirmframework.wffweb.informer.StateChangeInformer;
import com.webfirmframework.wffweb.util.StringUtil;
import com.webfirmframework.wffweb.util.TagStringUtil;

/**
 * 
 * The margin shorthand property sets all the margin properties in one declaration. This property can have from one to four values.
 *
 * Examples:
 *
 *     margin:10px 5px 15px 20px;
 *         top margin is 10px
 *         right margin is 5px
 *         bottom margin is 15px
 *         left margin is 20px
 *
 *     margin:10px 5px 15px;
 *         top margin is 10px
 *         right and left margin are 5px
 *         bottom margin is 15px
 *
 *     margin:10px 5px;
 *         top and bottom margin are 10px
 *         right and left margin are 5px
 *
 *     margin:10px;
 *         all four margins are 10px
 *
 * Note: Negative values are not allowed.
 * Default value:  0
 * Inherited:      no
 * Animatable:     yes
 *
 * Version:        CSS1
 * JavaScript syntax:      object.style.margin="100px 20px"
 * 
* * * @author WFF * @since 1.0.0 */ public class Margin extends AbstractCssProperty implements StateChangeInformer { private static final long serialVersionUID = 1_0_0L; public static final Logger LOGGER = Logger .getLogger(Margin.class.getName()); public static final String INITIAL = "initial"; public static final String INHERIT = "inherit"; private static final String AUTO = "auto"; private static final List PREDEFINED_CONSTANTS = Arrays .asList(INITIAL, INHERIT, AUTO); private String cssValue; private MarginTop marginTop; private MarginRight marginRight; private MarginBottom marginBottom; private MarginLeft marginLeft; /** * The {@code initial} will be set as the value */ public Margin() { setCssValue(INITIAL); } /** * @param cssValue * the css value to set. */ public Margin(final String cssValue) { setCssValue(cssValue); } /** * @param marginBottom * the {@code MarginBottom} object from which the cssValue to * set.And, {@code null} will throw {@code NullValueException} */ public Margin(final Margin marginBottom) { if (marginBottom == null) { throw new NullValueException("marginBottom can not be null"); } setCssValue(marginBottom.getCssValue()); } /** * the margin length to set. The alternative method {@code setCssValue} can * also be used. * * @param value * @return the current object * @since 1.0.0 * @author WFF */ public Margin setValue(final String value) { setCssValue(value); return this; } /* * (non-Javadoc) * * @see com.webfirmframework.wffweb.css.CssProperty#getCssName() * * @since 1.0.0 * * @author WFF */ @Override public String getCssName() { return CssNameConstants.MARGIN; } /* * (non-Javadoc) * * @see com.webfirmframework.wffweb.css.CssProperty#getCssValue() * * @since 1.0.0 * * @author WFF */ @Override public String getCssValue() { return cssValue; } @Override public String toString() { return getCssName() + ": " + getCssValue(); } /** * gets the value, {@code getCssValue} method can also be used to get the * same value. * * @return the value in String. * @since 1.0.0 * @author WFF */ public String getValue() { return getCssValue(); } /** * @param cssValue * the value should be a length value, for example * 5px. {@code null} is considered as an invalid * value and it will throw {@code NullValueException}.And an * empty string is also considered as an invalid value and it * will throw {@code InvalidValueException}. * @since 1.0.0 * @author WFF */ @Override public Margin setCssValue(final String cssValue) { if (cssValue == null) { throw new NullValueException( "null is an invalid value. The value should be css length for example 2px. Or, initial/inherit."); } else if (cssValue.trim().isEmpty()) { throw new InvalidValueException( "blank string is an invalid value. The value should be css length for example 5px. Or, initial/inherit."); } else { final String trimmedCssValue = cssValue.trim(); if (PREDEFINED_CONSTANTS.contains(trimmedCssValue)) { this.cssValue = trimmedCssValue; if (marginTop != null) { marginTop.setAlreadyInUse(false); marginTop = null; } if (marginRight != null) { marginRight.setAlreadyInUse(false); marginRight = null; } if (marginBottom != null) { marginBottom.setAlreadyInUse(false); marginBottom = null; } if (marginLeft != null) { marginLeft.setAlreadyInUse(false); marginLeft = null; } if (getStateChangeInformer() != null) { getStateChangeInformer().stateChanged(this); } return this; } final String marginString = StringUtil .convertToSingleSpace(trimmedCssValue); final String[] extractedMargins = marginString.split(" "); if (extractedMargins.length == 1) { if (marginTop == null) { marginTop = new MarginTop(extractedMargins[0]); marginTop.setStateChangeInformer(this); marginTop.setAlreadyInUse(true); } else { marginTop.setCssValue(extractedMargins[0]); } if (marginRight == null) { marginRight = new MarginRight(extractedMargins[0]); marginRight.setStateChangeInformer(this); marginRight.setAlreadyInUse(true); } else { marginRight.setCssValue(extractedMargins[0]); } if (marginBottom == null) { marginBottom = new MarginBottom(extractedMargins[0]); marginBottom.setStateChangeInformer(this); marginBottom.setAlreadyInUse(true); } else { marginBottom.setCssValue(extractedMargins[0]); } if (marginLeft == null) { marginLeft = new MarginLeft(extractedMargins[0]); marginLeft.setStateChangeInformer(this); marginLeft.setAlreadyInUse(true); } else { marginLeft.setCssValue(extractedMargins[0]); } } else if (extractedMargins.length == 2) { if (marginTop == null) { marginTop = new MarginTop(extractedMargins[0]); marginTop.setStateChangeInformer(this); marginTop.setAlreadyInUse(true); } else { marginTop.setCssValue(extractedMargins[0]); } if (marginBottom == null) { marginBottom = new MarginBottom(extractedMargins[0]); marginBottom.setStateChangeInformer(this); marginBottom.setAlreadyInUse(true); } else { marginBottom.setCssValue(extractedMargins[0]); } if (marginRight == null) { marginRight = new MarginRight(extractedMargins[1]); marginRight.setStateChangeInformer(this); marginRight.setAlreadyInUse(true); } else { marginRight.setCssValue(extractedMargins[1]); } if (marginLeft == null) { marginLeft = new MarginLeft(extractedMargins[1]); marginLeft.setStateChangeInformer(this); marginLeft.setAlreadyInUse(true); } else { marginLeft.setCssValue(extractedMargins[1]); } } else if (extractedMargins.length == 3) { if (marginTop == null) { marginTop = new MarginTop(extractedMargins[0]); marginTop.setStateChangeInformer(this); marginTop.setAlreadyInUse(true); } else { marginTop.setCssValue(extractedMargins[0]); } if (marginRight == null) { marginRight = new MarginRight(extractedMargins[1]); marginRight.setStateChangeInformer(this); marginRight.setAlreadyInUse(true); } else { marginRight.setCssValue(extractedMargins[1]); } if (marginLeft == null) { marginLeft = new MarginLeft(extractedMargins[1]); marginLeft.setStateChangeInformer(this); marginLeft.setAlreadyInUse(true); } else { marginLeft.setCssValue(extractedMargins[1]); } if (marginBottom == null) { marginBottom = new MarginBottom(extractedMargins[2]); marginBottom.setStateChangeInformer(this); marginBottom.setAlreadyInUse(true); } else { marginBottom.setCssValue(extractedMargins[2]); } } else if (extractedMargins.length == 4) { if (marginTop == null) { marginTop = new MarginTop(extractedMargins[0]); marginTop.setStateChangeInformer(this); marginTop.setAlreadyInUse(true); } else { marginTop.setCssValue(extractedMargins[0]); } if (marginRight == null) { marginRight = new MarginRight(extractedMargins[1]); marginRight.setStateChangeInformer(this); marginRight.setAlreadyInUse(true); } else { marginRight.setCssValue(extractedMargins[1]); } if (marginBottom == null) { marginBottom = new MarginBottom(extractedMargins[2]); marginBottom.setStateChangeInformer(this); marginBottom.setAlreadyInUse(true); } else { marginBottom.setCssValue(extractedMargins[2]); } if (marginLeft == null) { marginLeft = new MarginLeft(extractedMargins[3]); marginLeft.setStateChangeInformer(this); marginLeft.setAlreadyInUse(true); } else { marginLeft.setCssValue(extractedMargins[3]); } } else { throw new InvalidValueException( "the given cssValue is invalid"); } this.cssValue = marginString; if (getStateChangeInformer() != null) { getStateChangeInformer().stateChanged(this); } } return this; } /** * sets as {@code initial} * * @since 1.0.0 * @author WFF */ public void setAsInitial() { setCssValue(INITIAL); } /** * sets as {@code inherit} * * @since 1.0.0 * @author WFF */ public void setAsInherit() { setCssValue(INHERIT); } /** * sets as {@code inherit} * * @since 1.0.0 * @author WFF */ public void setAsAuto() { setCssValue(AUTO); } /** * @return the marginTop * @author WFF * @since 1.0.0 */ public MarginTop getMarginTop() { return marginTop; } /** * sets the top, right, bottom & left width in {@code Margin}. If the given * argument is already used by another object, then the existing/cloned * object will be used. And throws {@code NullValueException} if any of the * given argument is null. * * @param marginTop * @param marginRight * @param marginBottom * @param marginLeft * @author WFF * @since 1.0.0 */ public void setMargin(final MarginTop marginTop, final MarginRight marginRight, final MarginBottom marginBottom, final MarginLeft marginLeft) { if (marginTop != null && marginRight != null && marginBottom != null && marginLeft != null) { if (MarginTop.INITIAL.equals(marginTop.getCssValue()) || MarginTop.INHERIT.equals(marginTop.getCssValue()) || MarginRight.INITIAL.equals(marginRight.getCssValue()) || MarginRight.INHERIT.equals(marginRight.getCssValue()) || MarginBottom.INITIAL.equals(marginBottom.getCssValue()) || MarginBottom.INHERIT.equals(marginBottom.getCssValue()) || MarginLeft.INITIAL.equals(marginLeft.getCssValue()) || MarginLeft.INHERIT.equals(marginLeft.getCssValue())) { throw new InvalidValueException( "Any or all of the given arguments have initial/inherit constant value as its cssValue"); } try { final MarginTop marginTopTemp; final MarginRight marginRightTemp; final MarginBottom marginBottomTemp; final MarginLeft marginLeftTemp; if (this.marginTop != null) { this.marginTop.setAlreadyInUse(false); this.marginRight.setAlreadyInUse(false); this.marginBottom.setAlreadyInUse(false); this.marginLeft.setAlreadyInUse(false); } if (marginTop.isAlreadyInUse() && this.marginTop != marginTop) { if (this.marginTop != null) { marginTopTemp = this.marginTop .setCssValue(marginTop.getCssValue()); LOGGER.warning( "the given marginTop is already used by another object so the existing object is used"); } else { marginTopTemp = marginTop.clone(); LOGGER.warning( "the given marginTop is already used by another object so its clone is assigned"); } } else { marginTopTemp = marginTop; } if (marginRight.isAlreadyInUse() && this.marginRight != marginRight) { if (this.marginRight != null) { marginRightTemp = this.marginRight .setCssValue(marginTop.getCssValue()); LOGGER.warning( "the given marginRight is already used by another object so the existing object is used"); } else { marginRightTemp = marginRight.clone(); LOGGER.warning( "the given marginRight is already used by another object so its clone is assigned"); } } else { marginRightTemp = marginRight; } if (marginBottom.isAlreadyInUse() && this.marginBottom != marginBottom) { if (this.marginBottom != null) { marginBottomTemp = this.marginBottom .setCssValue(marginTop.getCssValue()); LOGGER.warning( "the given marginBottom is already used by another object so the existing object is used"); } else { marginBottomTemp = marginBottom.clone(); LOGGER.warning( "the given marginBottom is already used by another object so its clone is assigned"); } } else { marginBottomTemp = marginBottom; } if (marginLeft.isAlreadyInUse() && this.marginLeft != marginLeft) { if (this.marginLeft != null) { marginLeftTemp = this.marginLeft .setCssValue(marginTop.getCssValue()); LOGGER.warning( "the given marginLeft is already used by another object so the existing object is used"); } else { marginLeftTemp = marginLeft.clone(); LOGGER.warning( "the given marginLeft is already used by another object so its clone is assigned"); } } else { marginLeftTemp = marginLeft; } marginTopTemp.setAlreadyInUse(true); marginTopTemp.setStateChangeInformer(this); marginRightTemp.setAlreadyInUse(true); marginRightTemp.setStateChangeInformer(this); marginBottomTemp.setAlreadyInUse(true); marginBottomTemp.setStateChangeInformer(this); marginLeftTemp.setAlreadyInUse(true); marginLeftTemp.setStateChangeInformer(this); assignProducedCssValue(marginTop, marginRight, marginBottom, marginLeft); this.marginTop = marginTopTemp; this.marginRight = marginRightTemp; this.marginBottom = marginBottomTemp; this.marginLeft = marginLeftTemp; } catch (final CloneNotSupportedException e) { throw new InvalidValueException(e); } catch (final Exception e) { throw new InvalidValueException(e); } } else { throw new NullValueException("cannot accept null arguments"); } } /** * @return the marginRight * @author WFF * @since 1.0.0 */ public MarginRight getMarginRight() { return marginRight; } /** * @return the marginBottom * @author WFF * @since 1.0.0 */ public MarginBottom getMarginBottom() { return marginBottom; } /** * @return the marginLeft * @author WFF * @since 1.0.0 */ public MarginLeft getMarginLeft() { return marginLeft; } /** * * @author WFF * @since 1.0.0 */ private void assignProducedCssValue(final MarginTop marginTop, final MarginRight marginRight, final MarginBottom marginBottom, final MarginLeft marginLeft) { final String marginTopCssValue = marginTop.getCssValue(); final String marginRightCssValue = marginRight.getCssValue(); final String marginBottomCssValue = marginBottom.getCssValue(); final String marginLeftCssValue = marginLeft.getCssValue(); if (marginTopCssValue.equals(marginRightCssValue) && marginRightCssValue.equals(marginBottomCssValue) && marginBottomCssValue.equals(marginLeftCssValue)) { cssValue = marginTopCssValue; final StateChangeInformer stateChangeInformer = getStateChangeInformer(); if (stateChangeInformer != null) { stateChangeInformer.stateChanged(this); } } else if (marginTopCssValue.equals(marginBottomCssValue) && marginRightCssValue.equals(marginLeftCssValue)) { final StringBuilder cssValueBuilder = new StringBuilder( marginTopCssValue); cssValueBuilder.append(" "); cssValueBuilder.append(marginRightCssValue); cssValue = cssValueBuilder.toString(); final StateChangeInformer stateChangeInformer = getStateChangeInformer(); if (stateChangeInformer != null) { stateChangeInformer.stateChanged(this); } } else if (marginRightCssValue.equals(marginLeftCssValue)) { final StringBuilder cssValueBuilder = new StringBuilder( marginTopCssValue); cssValueBuilder.append(" "); cssValueBuilder.append(marginRightCssValue); cssValueBuilder.append(" "); cssValueBuilder.append(marginBottomCssValue); cssValue = cssValueBuilder.toString(); final StateChangeInformer stateChangeInformer = getStateChangeInformer(); if (stateChangeInformer != null) { stateChangeInformer.stateChanged(this); } } else { final StringBuilder cssValueBuilder = new StringBuilder( marginTopCssValue); cssValueBuilder.append(" "); cssValueBuilder.append(marginRightCssValue); cssValueBuilder.append(" "); cssValueBuilder.append(marginBottomCssValue); cssValueBuilder.append(" "); cssValueBuilder.append(marginLeftCssValue); cssValue = cssValueBuilder.toString(); final StateChangeInformer stateChangeInformer = getStateChangeInformer(); if (stateChangeInformer != null) { stateChangeInformer.stateChanged(this); } } } /* * (non-Javadoc) * * @see * com.webfirmframework.wffweb.informer.StateChangeInformer#stateChanged( * java.lang .Object) */ @Override public void stateChanged(final CssProperty stateChangedObject) { if (stateChangedObject instanceof MarginTop) { final MarginTop marginTop = (MarginTop) stateChangedObject; if (MarginTop.INITIAL.equals(marginTop.getCssValue()) || MarginTop.INHERIT.equals(marginTop.getCssValue())) { throw new InvalidValueException( "marginTop cannot have initial/inherit as its cssValue"); } } else if (stateChangedObject instanceof MarginRight) { final MarginRight marginRight = (MarginRight) stateChangedObject; if (MarginRight.INITIAL.equals(marginRight.getCssValue()) || MarginRight.INHERIT.equals(marginRight.getCssValue())) { throw new InvalidValueException( "marginRight cannot have initial/inherit as its cssValue"); } } else if (stateChangedObject instanceof MarginBottom) { final MarginBottom marginBottom = (MarginBottom) stateChangedObject; if (MarginBottom.INITIAL.equals(marginBottom.getCssValue()) || MarginBottom.INHERIT .equals(marginBottom.getCssValue())) { throw new InvalidValueException( "marginBottom cannot have initial/inherit as its cssValue"); } } else if (stateChangedObject instanceof MarginLeft) { final MarginLeft marginLeft = (MarginLeft) stateChangedObject; if (MarginLeft.INITIAL.equals(marginLeft.getCssValue()) || MarginLeft.INHERIT.equals(marginLeft.getCssValue())) { throw new InvalidValueException( "marginLeft cannot have initial/inherit as its cssValue"); } } assignProducedCssValue(marginTop, marginRight, marginBottom, marginLeft); } /** * @return true if its cssValue is any of the values * initial, inherit or transparent. * @author WFF * @since 1.0.0 */ public boolean hasPredefinedConstantValue() { return PREDEFINED_CONSTANTS.contains(cssValue); } /** * * @author WFF * @since 1.0.0 */ public static boolean isValid(final String cssValue) { final String trimmedCssValue; if (cssValue == null || (trimmedCssValue = TagStringUtil .toLowerCase(cssValue.trim())).isEmpty()) { return false; } if (PREDEFINED_CONSTANTS.contains(trimmedCssValue)) { return true; } final String[] cssValueParts = trimmedCssValue.split(" "); for (final String eachPart : cssValueParts) { final boolean valid = MarginTop.isValid(eachPart); if ((valid && (INITIAL.equals(eachPart) || INHERIT.equals(eachPart))) || !valid) { return false; } } return true; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy