gt: 		if (oldModel != null)
context: /*******************************************************************************
   * Copyright (c) 2004, 2009 IBM Corporation 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:
   *     IBM Corporation - initial API and implementation
   *******************************************************************************/
  package org.eclipse.wst.html.core.internal.htmlcss;
  import java.io.IOException;
  import java.io.UnsupportedEncodingException;
  
  import org.eclipse.core.runtime.IPath;
  import org.eclipse.core.runtime.Path;
  import org.eclipse.wst.css.core.internal.provisional.adapters.IModelProvideAdapter;
  import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetListAdapter;
  import org.eclipse.wst.css.core.internal.provisional.contenttype.ContentTypeIdForCSS;
  import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
  import org.eclipse.wst.html.core.internal.provisional.HTML40Namespace;
  import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
  import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
  import org.eclipse.wst.sse.core.internal.util.URIResolver;
  import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
  import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  
  /**
   */
  public class LinkElementAdapter extends AbstractStyleSheetAdapter {
  
  	private final static String CSS_ID = ContentTypeIdForCSS.ContentTypeID_CSS;
  	private boolean replaceModel = true;
  	// this variable to hold the class is just a VAJava trick.
  	// it improves performance in VAJava by minimizing class loading.
  	private final Class ModelProvideAdapterClass = IModelProvideAdapter.class;
  
  	/**
  	 */
  	protected LinkElementAdapter() {
  		super();
  	}
  
  	/**
  	 */
  	private void attrReplaced() {
  		this.replaceModel = true;
  
  		Element element = getElement();
  		if (element == null)
  			return; // error
  		Document document = element.getOwnerDocument();
  		if (document == null)
  			return; // error
  		INodeNotifier notifier = (INodeNotifier) document;
  		HTMLDocumentAdapter adapter = (HTMLDocumentAdapter) notifier.getAdapterFor(IStyleSheetListAdapter.class);
  		if (adapter == null)
  			return;
  		adapter.childReplaced();
  	}
  
  	protected ICSSModel createModel() {
  		// create phantom(broken link) external CSS model
  		if (getElement() == null)
  			return null;
  		IStructuredModel baseModel = ((IDOMNode) getElement()).getModel();
  		ICSSModel newModel = (ICSSModel) baseModel.getModelManager().createUnManagedStructuredModelFor(CSS_ID);
  
  		// calculate base location and set
  		// get resolver in Model
  		URIResolver resolver = baseModel.getResolver();
  
  		// resolve to absolute url : this need not exact location of css file. It is important that absurl is not null. 
  		String ref = getElement().getAttribute(HTML40Namespace.ATTR_NAME_HREF);
  		String absurl = (resolver != null && ref != null && ref.length() > 0) ? resolver.getLocationByURI(ref, true) : null;
  		if ((absurl == null) || (absurl.length() == 0)) {
  			IPath basePath = new Path(baseModel.getBaseLocation());
  			URLHelper helper = new URLHelper(basePath.removeLastSegments(1).toString());
  			absurl = helper.toAbsolute(ref == null ? "" : ref);//$NON-NLS-1$
  		}
  		if ((absurl == null) || (absurl.length() == 0)) {
  			absurl = ref;
  		}
  		if (absurl == null) {
  			absurl = "";//$NON-NLS-1$
  		}
  		newModel.setBaseLocation(absurl);
  
  		// set style listener
  		newModel.addStyleListener(this);
  
  		return newModel;
  	}
  
  	/**
  	 */
  	public ICSSModel getModel() {
  		ICSSModel model = getExistingModel();
  		if (this.replaceModel) {
  			ICSSModel oldModel = model;
  			try {
  				model = retrieveModel();
  				setModel(model);
  
  				// release old model
  				if (oldModel != null) {
  					// get ModelProvideAdapter
  					IModelProvideAdapter adapter = (IModelProvideAdapter) ((INodeNotifier) getElement()).getAdapterFor(IModelProvideAdapter.class);
  					if (adapter != null)
  						adapter.modelRemoved(oldModel);
  				}
  			}
  			finally {
  				if (oldModel != null)
  					oldModel.releaseFromRead();
  			}
  			this.replaceModel = false;
  		}
  		return model;
  	}
  
  	/**
  	 */
  	public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
  		if (eventType != INodeNotifier.CHANGE)
  			return;
  		Attr attr = (Attr) changedFeature;
  		if (attr == null)
  			return;
  		String name = attr.getName();
  		if (name.equalsIgnoreCase("rel") || //$NON-NLS-1$
  					name.equalsIgnoreCase("type") || //$NON-NLS-1$	
  					name.equalsIgnoreCase("href")) {//$NON-NLS-1$
  			attrReplaced();
  		}
  	}
  
  	/**
  	 */
  	public void refreshSheet() {
  		if (!replaceModel) {
  			removed();
  			replaceModel = true;
  
  			IDOMNode node = (IDOMNode) getElement();
  			if (node != null) {
  				node.notify(INodeNotifier.CHANGE, getElement().getAttributeNode(org.eclipse.wst.html.core.internal.provisional.HTML40Namespace.ATTR_NAME_HREF), null, null, node.getStartOffset());
  			}
  		}
  	}
  
  	/**
  	 */
  	public void released() {
  		ICSSModel model = getExistingModel();
  		if (model != null) {
  			try {
  				// get ModelProvideAdapter
  				IModelProvideAdapter adapter = (IModelProvideAdapter) ((INodeNotifier) getElement()).getAdapterFor(IModelProvideAdapter.class);
  
  				// set element to null first, so that no document wide updates
  				setElement(null);
  				setModel(null);
  
  				if (adapter != null)
  					adapter.modelReleased(model);
  			}
  			finally {
  				model.releaseFromRead();
  			}
  		}
  		this.replaceModel = false;
  	}
  
  	/**
  	 */
  	public void removed() {
  		ICSSModel model = getExistingModel();
  		if (model != null) {
  			try {
  				setModel(null);
  
  				// get ModelProvideAdapter
  				IModelProvideAdapter adapter = (IModelProvideAdapter) ((INodeNotifier) getElement()).getAdapterFor(IModelProvideAdapter.class);
  				if (adapter != null)
  					adapter.modelRemoved(model);
  			}
  			finally {
  				model.releaseFromRead();
  			}
  		}
  		this.replaceModel = false;
  	}
  
  	/**
  	 */
  	protected boolean isValidAttribute() {
  		Element element = getElement();
  		if (element == null)
  			return false;
  		if (!element.hasAttribute("rel") || !"stylesheet".equalsIgnoreCase(element.getAttribute("rel")))//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  			return false;
  		if (element.hasAttribute("type") && !"text/css".equalsIgnoreCase(element.getAttribute("type")))//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  			return false;
  		if (!element.hasAttribute("href") || element.getAttribute("href").length() == 0) //$NON-NLS-1$ //$NON-NLS-2$
  			return false;
  		return true;
  	}
  
  	/**
  	 */
  	private ICSSModel retrieveModel() {
  		if (!isValidAttribute()) {
  			return null;
  		}
  
  		// null,attr check is done in isValidAttribute()
  		Element element = getElement();
  		String href = element.getAttribute("href");//$NON-NLS-1$
  
  		IDOMModel baseModel = ((IDOMNode) element).getModel();
  		if (baseModel == null)
  			return null;
  		Object id = baseModel.getId();
  		if (!(id instanceof String))
  			return null;
  		//String base = (String)id;
  
  		// get ModelProvideAdapter
  		IModelProvideAdapter adapter = (IModelProvideAdapter) ((INodeNotifier) getElement()).getAdapterFor(ModelProvideAdapterClass);
  
  		URLModelProvider provider = new URLModelProvider();
  		try {
  			IStructuredModel newModel = provider.getModelForRead(baseModel, href);
  			if (newModel == null)
  				return null;
  			if (!(newModel instanceof ICSSModel)) {
  				newModel.releaseFromRead();
  				return null;
  			}
  
  			// notify adapter
  			if (adapter != null)
  				adapter.modelProvided(newModel);
  
  			return (ICSSModel) newModel;
  		}
  		catch (UnsupportedEncodingException e) {
  		}
  		catch (IOException e) {
  		}
  
  		return null;
  	}
  
  	/**
  	 */
  	protected void setModel(ICSSModel model) {
  		ICSSModel oldModel = getExistingModel();
  		if (model == oldModel)
  			return;
  		super.setModel(model);
  		if (this.replaceModel)
  			this.replaceModel = false;
  