/* * Copyright (c) 2003-2004 Christopher Lenz and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * Christopher Lenz - initial API and implementation * * $Id: StyleSheet.java,v 1.1 2004-09-02 18:07:12 jsurfer Exp $ */ package net.sourceforge.phpeclipse.css.core.internal.model; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.sourceforge.phpeclipse.core.model.SourceReference; import net.sourceforge.phpeclipse.css.core.internal.parser.DefaultCssParser; import net.sourceforge.phpeclipse.css.core.model.IRule; import net.sourceforge.phpeclipse.css.core.model.IStyleSheet; import net.sourceforge.phpeclipse.css.core.parser.ICssParser; import net.sourceforge.phpeclipse.css.core.parser.IProblemCollector; import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException; import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jface.text.IRegion; /** * */ public class StyleSheet extends SourceReference implements IStyleSheet, IDocumentListener { // Instance Variables ------------------------------------------------------ /** * The list of top-level CSS rules defined in the style sheet. */ private List rules = new ArrayList(); private Object dirtyLock = new Object(); private boolean dirty = true; // Constructors ------------------------------------------------------------ /** * Constructor. * * @param document The document that contains the style sheet */ public StyleSheet(IDocument document) { super(document); } // IAdaptable Implementation ----------------------------------------------- /* * @see IAdaptable#getAdapter(Class) */ public Object getAdapter(Class adapter) { return Platform.getAdapterManager().getAdapter(this, adapter); } // IStyleSheet Implementation ---------------------------------------------- /* * @see IStyleSheet#getRuleAt(int) */ public IRule getRuleAt(int offset) { return getRuleAtInternal(getRules(), offset); } /* * @see IStyleSheet#getRules() */ public IRule[] getRules() { return (IRule[]) rules.toArray(new IRule[rules.size()]); } /* * @see IStyleSheet#reconcile(IProblemCollector) */ public void reconcile(IProblemCollector problemCollector) throws LexicalErrorException, SyntaxErrorException { synchronized (dirtyLock) { if (!dirty) { return; } dirty = false; } synchronized (this) { rules.clear(); ICssParser parser = new DefaultCssParser(); parser.setProblemCollector(problemCollector); parser.setSource(getDocument()); rules.addAll(Arrays.asList(parser.parseRules(this))); } } // IDocumentListener Implementation ---------------------------------------- /* * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) */ public void documentAboutToBeChanged(DocumentEvent event) { // do nothing yet } /* * @see IDocumentListener#documentChanged(DocumentEvent) */ public void documentChanged(DocumentEvent event) { synchronized (dirtyLock) { dirty = true; } } // Public Methods ---------------------------------------------------------- /** * Adds a rule to the style sheet. * * @param rule The rule to add */ public void addRule(IRule rule) { rules.add(rule); } // Private Methods --------------------------------------------------------- private static IRule getRuleAtInternal(IRule rules[], int offset) { IRule retVal = null; for (int i = 0; i < rules.length; i++) { IRule rule = rules[i]; IRegion region = rule.getSourceRegion(); if ((offset > region.getOffset()) && (offset < (region.getOffset() + region.getLength()))) { if (rule.getChildren().length > 0) { retVal = getRuleAtInternal(rule.getChildren(), offset); if (retVal != null) { break; } } if (retVal == null) { retVal = rule; } } } return retVal; } }