/*
 * Copyright (c) 2010-2013, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *
 * $Id: NotUnsettableWithDefault.java,v 1.2 2011-01-01 11:01:58 estepper Exp $
 */
package org.eclipse.emf.cdo.tests.model2;

import org.eclipse.emf.cdo.tests.model1.VAT;

import org.eclipse.emf.ecore.EObject;

import java.util.Date;

/**
 * <!-- begin-user-doc --> A representation of the model object '<em><b>Not Unsettable With Default</b></em>'. <!--
 * end-user-doc -->
 *
 * <p>
 * The following features are supported:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#isNotUnsettableBoolean <em>Not Unsettable Boolean</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableByte <em>Not Unsettable Byte</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableChar <em>Not Unsettable Char</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableDate <em>Not Unsettable Date</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableDouble <em>Not Unsettable Double</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableFloat <em>Not Unsettable Float</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableInt <em>Not Unsettable Int</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableLong <em>Not Unsettable Long</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableShort <em>Not Unsettable Short</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableString <em>Not Unsettable String</em>}</li>
 *   <li>{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableVAT <em>Not Unsettable VAT</em>}</li>
 * </ul>
 *
 * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault()
 * @model
 * @generated
 */
public interface NotUnsettableWithDefault extends EObject
{
  /**
   * Returns the value of the '<em><b>Not Unsettable Boolean</b></em>' attribute.
   * The default value is <code>"true"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Boolean</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Boolean</em>' attribute.
   * @see #setNotUnsettableBoolean(boolean)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableBoolean()
   * @model default="true"
   * @generated
   */
  boolean isNotUnsettableBoolean();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#isNotUnsettableBoolean <em>Not Unsettable Boolean</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Boolean</em>' attribute.
   * @see #isNotUnsettableBoolean()
   * @generated
   */
  void setNotUnsettableBoolean(boolean value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Byte</b></em>' attribute.
   * The default value is <code>"3"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Byte</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Byte</em>' attribute.
   * @see #setNotUnsettableByte(byte)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableByte()
   * @model default="3"
   * @generated
   */
  byte getNotUnsettableByte();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableByte <em>Not Unsettable Byte</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Byte</em>' attribute.
   * @see #getNotUnsettableByte()
   * @generated
   */
  void setNotUnsettableByte(byte value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Char</b></em>' attribute.
   * The default value is <code>"\'x\'"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Char</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Char</em>' attribute.
   * @see #setNotUnsettableChar(char)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableChar()
   * @model default="\'x\'"
   * @generated
   */
  char getNotUnsettableChar();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableChar <em>Not Unsettable Char</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Char</em>' attribute.
   * @see #getNotUnsettableChar()
   * @generated
   */
  void setNotUnsettableChar(char value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Date</b></em>' attribute.
   * The default value is <code>"1979-03-15T07:12:59"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Date</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Date</em>' attribute.
   * @see #setNotUnsettableDate(Date)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableDate()
   * @model default="1979-03-15T07:12:59"
   * @generated
   */
  Date getNotUnsettableDate();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableDate <em>Not Unsettable Date</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Date</em>' attribute.
   * @see #getNotUnsettableDate()
   * @generated
   */
  void setNotUnsettableDate(Date value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Double</b></em>' attribute.
   * The default value is <code>"3.3"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Double</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Double</em>' attribute.
   * @see #setNotUnsettableDouble(double)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableDouble()
   * @model default="3.3"
   * @generated
   */
  double getNotUnsettableDouble();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableDouble <em>Not Unsettable Double</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Double</em>' attribute.
   * @see #getNotUnsettableDouble()
   * @generated
   */
  void setNotUnsettableDouble(double value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Float</b></em>' attribute.
   * The default value is <code>"4.4"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Float</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Float</em>' attribute.
   * @see #setNotUnsettableFloat(float)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableFloat()
   * @model default="4.4"
   * @generated
   */
  float getNotUnsettableFloat();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableFloat <em>Not Unsettable Float</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Float</em>' attribute.
   * @see #getNotUnsettableFloat()
   * @generated
   */
  void setNotUnsettableFloat(float value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Int</b></em>' attribute.
   * The default value is <code>"5"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Int</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Int</em>' attribute.
   * @see #setNotUnsettableInt(int)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableInt()
   * @model default="5"
   * @generated
   */
  int getNotUnsettableInt();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableInt <em>Not Unsettable Int</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Int</em>' attribute.
   * @see #getNotUnsettableInt()
   * @generated
   */
  void setNotUnsettableInt(int value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Long</b></em>' attribute.
   * The default value is <code>"6"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Long</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Long</em>' attribute.
   * @see #setNotUnsettableLong(long)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableLong()
   * @model default="6"
   * @generated
   */
  long getNotUnsettableLong();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableLong <em>Not Unsettable Long</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Long</em>' attribute.
   * @see #getNotUnsettableLong()
   * @generated
   */
  void setNotUnsettableLong(long value);

  /**
   * Returns the value of the '<em><b>Not Unsettable Short</b></em>' attribute.
   * The default value is <code>"7"</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable Short</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable Short</em>' attribute.
   * @see #setNotUnsettableShort(short)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableShort()
   * @model default="7"
   * @generated
   */
  short getNotUnsettableShort();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableShort <em>Not Unsettable Short</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable Short</em>' attribute.
   * @see #getNotUnsettableShort()
   * @generated
   */
  void setNotUnsettableShort(short value);

  /**
   * Returns the value of the '<em><b>Not Unsettable String</b></em>' attribute.
   * The default value is <code>"\"eike\""</code>.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable String</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable String</em>' attribute.
   * @see #setNotUnsettableString(String)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableString()
   * @model default="\"eike\""
   * @generated
   */
  String getNotUnsettableString();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableString <em>Not Unsettable String</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable String</em>' attribute.
   * @see #getNotUnsettableString()
   * @generated
   */
  void setNotUnsettableString(String value);

  /**
   * Returns the value of the '<em><b>Not Unsettable VAT</b></em>' attribute.
   * The default value is <code>"vat15"</code>.
   * The literals are from the enumeration {@link org.eclipse.emf.cdo.tests.model1.VAT}.
   * <!-- begin-user-doc -->
   * <p>
   * If the meaning of the '<em>Not Unsettable VAT</em>' attribute isn't clear, there really should be more of a
   * description here...
   * </p>
   * <!-- end-user-doc -->
   * @return the value of the '<em>Not Unsettable VAT</em>' attribute.
   * @see org.eclipse.emf.cdo.tests.model1.VAT
   * @see #setNotUnsettableVAT(VAT)
   * @see org.eclipse.emf.cdo.tests.model2.Model2Package#getNotUnsettableWithDefault_NotUnsettableVAT()
   * @model default="vat15"
   * @generated
   */
  VAT getNotUnsettableVAT();

  /**
   * Sets the value of the '{@link org.eclipse.emf.cdo.tests.model2.NotUnsettableWithDefault#getNotUnsettableVAT <em>Not Unsettable VAT</em>}' attribute.
   * <!-- begin-user-doc --> <!-- end-user-doc -->
   * @param value the new value of the '<em>Not Unsettable VAT</em>' attribute.
   * @see org.eclipse.emf.cdo.tests.model1.VAT
   * @see #getNotUnsettableVAT()
   * @generated
   */
  void setNotUnsettableVAT(VAT value);

} // NotUnsettableWithDefault
