/*******************************************************************************
* Copyright (c) 2007, 2016 Red Hat, Inc.
* 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:
* Red Hat - initial API and implementation
* Alphonse Van Assche
*******************************************************************************/
package org.eclipse.linuxtools.rpm.ui.editor.parser;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.linuxtools.internal.rpm.ui.editor.RpmTags;
import org.eclipse.linuxtools.internal.rpm.ui.editor.UiUtils;
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SourceComparator;
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfilePreamble;
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfileSource;
import org.eclipse.linuxtools.internal.rpm.ui.editor.parser.SpecfileTag;
public class Specfile {
private SpecfilePreamble preamble;
private SpecfilePackageContainer packages;
private List<SpecfileSection> sections;
private List<SpecfileSection> complexSections;
private Map<String, SpecfileDefine> defines;
private Map<Integer, SpecfileSource> sources;
private Map<Integer, SpecfileSource> patches;
private List<SpecfileTag> buildRequires;
private List<SpecfileTag> requires;
private IDocument document;
public Specfile() {
packages = new SpecfilePackageContainer();
preamble = new SpecfilePreamble();
sections = new ArrayList<>();
complexSections = new ArrayList<>();
defines = new HashMap<>();
sources = new HashMap<>();
patches = new HashMap<>();
buildRequires = new ArrayList<>();
requires = new ArrayList<>();
}
public List<SpecfileSection> getSections() {
return sections;
}
public SpecfileSection getSection(String sectionName){
for (SpecfileSection section : sections) {
if (sectionName.equals(section.getName())) {
return section;
}
}
return null;
}
public List<SpecfileSection> getComplexSections() {
return complexSections;
}
public SpecfileSource getPatch(int number) {
return patches.get(number);
}
public SpecfileSource getSource(int number) {
return sources.get(number);
}
public String getName() {
SpecfileDefine define = getDefine(RpmTags.NAME.toLowerCase());
if (define != null){
return define.getStringValue();
}
return " "; //$NON-NLS-1$
}
public void addSection(SpecfileSection section) {
sections.add(section);
}
public void addComplexSection(SpecfileSection section) {
complexSections.add(section);
}
public void addSource(SpecfileSource source) {
sources.put(Integer.valueOf(source.getNumber()), source);
}
public void addPatch(SpecfileSource patch) {
patches.put(Integer.valueOf(patch.getNumber()), patch);
}
/**
* Adds the given define to the map of defines for this specfile.
*
* @param define The define to add.
*/
public void addDefine(SpecfileDefine define) {
SpecfilePackage rpmPackage = define.getParent();
if (rpmPackage != null && !rpmPackage.isMainPackage()) {
defines.put(UiUtils.getPackageDefineId(define, rpmPackage), define);
return;
}
defines.put(define.getName(), define);
}
public void addDefine(SpecfileTag tag) {
addDefine(new SpecfileDefine(tag));
}
public SpecfileDefine getDefine(String defineName) {
return defines.get(defineName.toLowerCase());
}
public SpecfileDefine getDefine(String defineName, SpecfilePackage rpmPackage) {
return defines.get(UiUtils.getPackageDefineId(defineName, rpmPackage));
}
public int getEpoch() {
SpecfileDefine define = getDefine(RpmTags.EPOCH.toLowerCase());
if (define != null){
return define.getIntValue();
}
return -1;
}
public String getRelease() {
SpecfileDefine define = getDefine(RpmTags.RELEASE.toLowerCase());
if (define != null){
return define.getStringValue();
}
return "0"; //$NON-NLS-1$
}
public String getBuildArch() {
SpecfileDefine define = getDefine(RpmTags.BUILD_ARCH.toLowerCase());
if (define != null){
return define.getStringValue();
}
return "0"; //$NON-NLS-1$
}
public String getVersion() {
SpecfileDefine define = getDefine(RpmTags.VERSION.toLowerCase());
if (define != null){
return define.getStringValue();
}
return "0"; //$NON-NLS-1$
}
public List<SpecfileSource> getPatches() {
List<SpecfileSource> patchesList = new ArrayList<>(patches.values());
Collections.sort(patchesList, new SourceComparator());
return patchesList;
}
public List<SpecfileSource> getSources() {
List<SpecfileSource> sourcesList = new ArrayList<>(sources.values());
Collections.sort(sourcesList, new SourceComparator());
return sourcesList;
}
public List<SpecfileDefine> getDefines() {
return new ArrayList<>(defines.values());
}
public void organizePatches() {
List<SpecfileSource> patches = getPatches();
int newPatchNumber = 0;
int oldPatchNumber = -1;
Map<Integer, SpecfileSource> newPatches = new HashMap<>();
for (SpecfileSource thisPatch : patches) {
if (thisPatch.getSpecfile() == null) {
thisPatch.setSpecfile(this);
}
oldPatchNumber = thisPatch.getNumber();
thisPatch.setNumber(newPatchNumber);
thisPatch.changeDeclaration(oldPatchNumber);
thisPatch.changeReferences(oldPatchNumber);
newPatches.put(Integer.valueOf(newPatchNumber), thisPatch);
newPatchNumber++;
}
setPatches(newPatches);
}
public void setDocument(IDocument specfileDocument) {
document = specfileDocument;
}
public String getLine(int lineNumber) throws BadLocationException {
int offset = document.getLineOffset(lineNumber);
int length = getLineLength(lineNumber);
return document.get(offset, length);
}
public IDocument getDocument() {
return document;
}
public int getLineLength(int lineNumber) throws BadLocationException {
int length = document.getLineLength(lineNumber);
String lineDelimiter = document.getLineDelimiter(lineNumber);
if (lineDelimiter != null) {
length = length - lineDelimiter.length();
}
return length;
}
public void changeLine(int lineNumber, String string)
throws BadLocationException {
document.replace(document.getLineOffset(lineNumber),
getLineLength(lineNumber), string);
}
public void setPatches(Map<Integer, SpecfileSource> patches) {
this.patches = patches;
}
@Override
public String toString() {
return getName();
}
public String getLicense() {
return defines.get(RpmTags.LICENSE.toLowerCase()).getStringValue();
}
public SpecfilePackageContainer getPackages() {
return packages;
}
public SpecfileElement getPreamble() {
return preamble;
}
public SpecfilePackage getPackage(String packageName) {
return getPackages().getPackage(packageName);
}
public void addPackage(SpecfilePackage subPackage) {
if (! packages.contains(subPackage)) {
packages.addPackage(subPackage);
}
}
public void modifyDefine(String defineName, SpecfilePackage rpmPackage,
String newValue) {
SpecfileDefine define = getDefine(UiUtils.getPackageDefineId(defineName, rpmPackage));
if (define != null) {
define.setValue(newValue);
try {
changeLine(define.getLineNumber(), defineName + ": " + newValue); //$NON-NLS-1$
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
public void modifyDefine(String defineName, String newValue) {
SpecfileDefine define = getDefine(defineName.toLowerCase());
if (define != null) {
define.setValue(newValue);
try {
changeLine(define.getLineNumber(), defineName + ": " + newValue); //$NON-NLS-1$
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
public void modifyDefine(SpecfileTag define, String newValue) {
if (define != null) {
define.setValue(newValue);
try {
changeLine(define.getLineNumber(), define.getName() + ": " + newValue); //$NON-NLS-1$
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
/**
* @param buildRequire the buildRequire to add
*/
public void addBuildRequire(SpecfileDefine buildRequire) {
buildRequires.add(buildRequire);
}
/**
* @param require the require to add
*/
public void addRequire(SpecfileTag require) {
requires.add(require);
}
/**
* @return the buildRequires
*/
public List<SpecfileTag> getBuildRequires() {
return buildRequires;
}
public List<SpecfileTag> getRequires() {
return requires;
}
}