
/************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * Use is subject to license terms.
 * 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 *
 ************************************************************************/

/*
 * This file is automatically generated.
 * Don't edit manually.
 */
package org.odftoolkit.odfdom.pkg.manifest;

import org.odftoolkit.odfdom.pkg.OdfElement;
import org.odftoolkit.odfdom.pkg.OdfFileDom;
import org.odftoolkit.odfdom.pkg.OdfName;
import org.odftoolkit.odfdom.pkg.OdfPackageNamespace;


/**
 * Manifest implementation of OpenDocument element  {@odf.element manifest:key-derivation}.
 *
 */
public class KeyDerivationElement extends OdfElement {

	public static final OdfName ELEMENT_NAME = OdfName.newName(OdfPackageNamespace.MANIFEST, "key-derivation");

	/**
	 * Create the instance of <code>KeyDerivationElement</code>
	 *
	 * @param  ownerDoc     The type is <code>OdfFileDom</code>
	 */
	public KeyDerivationElement(OdfFileDom ownerDoc) {
		super(ownerDoc, ELEMENT_NAME);
	}

	/**
	 * Get the element name
	 *
	 * @return  return   <code>OdfName</code> the name of element {@odf.element manifest:key-derivation}.
	 */
    @Override
	public OdfName getOdfName() {
		return ELEMENT_NAME;
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>IterationCountAttribute</code> , See {@odf.attribute manifest:iteration-count}
	 *
	 * Attribute is mandatory.
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getIterationCountAttribute() {
		IterationCountAttribute attr = (IterationCountAttribute) getOdfAttribute(OdfPackageNamespace.MANIFEST, "iteration-count");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>IterationCountAttribute</code> , See {@odf.attribute manifest:iteration-count}
	 *
	 * @param iterationCountValue   The type is <code>Integer</code>
	 */
	public void setIterationCountAttribute(Integer iterationCountValue) {
		IterationCountAttribute attr = new IterationCountAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(iterationCountValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>KeyDerivationNameAttribute</code> , See {@odf.attribute manifest:key-derivation-name}
	 *
	 * Attribute is mandatory.
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getKeyDerivationNameAttribute() {
		KeyDerivationNameAttribute attr = (KeyDerivationNameAttribute) getOdfAttribute(OdfPackageNamespace.MANIFEST, "key-derivation-name");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>KeyDerivationNameAttribute</code> , See {@odf.attribute manifest:key-derivation-name}
	 *
	 * @param keyDerivationNameValue   The type is <code>String</code>
	 */
	public void setKeyDerivationNameAttribute(String keyDerivationNameValue) {
		KeyDerivationNameAttribute attr = new KeyDerivationNameAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(keyDerivationNameValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>KeySizeAttribute</code> , See {@odf.attribute manifest:key-size}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getKeySizeAttribute() {
		KeySizeAttribute attr = (KeySizeAttribute) getOdfAttribute(OdfPackageNamespace.MANIFEST, "key-size");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>KeySizeAttribute</code> , See {@odf.attribute manifest:key-size}
	 *
	 * @param keySizeValue   The type is <code>Integer</code>
	 */
	public void setKeySizeAttribute(Integer keySizeValue) {
		KeySizeAttribute attr = new KeySizeAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(keySizeValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SaltAttribute</code> , See {@odf.attribute manifest:salt}
	 *
	 * Attribute is mandatory.
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSaltAttribute() {
		SaltAttribute attr = (SaltAttribute) getOdfAttribute(OdfPackageNamespace.MANIFEST, "salt");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SaltAttribute</code> , See {@odf.attribute manifest:salt}
	 *
	 * @param saltValue   The type is <code>String</code>
	 */
	public void setSaltAttribute(String saltValue) {
		SaltAttribute attr = new SaltAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(saltValue);
	}

}
